diff --git a/sdncon/.project b/sdncon/.project
new file mode 100644
index 0000000..0d62cb3
--- /dev/null
+++ b/sdncon/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>sdncon</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.python.pydev.PyDevBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.python.pydev.pythonNature</nature>
+	</natures>
+</projectDescription>
diff --git a/sdncon/.pydevproject b/sdncon/.pydevproject
new file mode 100644
index 0000000..037bd25
--- /dev/null
+++ b/sdncon/.pydevproject
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?eclipse-pydev version="1.0"?><pydev_project>
+<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
+<path>/${PROJECT_DIR_NAME}</path>
+</pydev_pathproperty>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
+</pydev_project>
diff --git a/sdncon/MANIFEST.in b/sdncon/MANIFEST.in
new file mode 100755
index 0000000..448171b
--- /dev/null
+++ b/sdncon/MANIFEST.in
@@ -0,0 +1,7 @@
+graft */templates
+graft */img
+graft */static
+graft apps/*/templates
+graft apps/*/img
+graft apps/*/static
+global-exclude tests.py
diff --git a/sdncon/__init__.py b/sdncon/__init__.py
new file mode 100755
index 0000000..f6d7d82
--- /dev/null
+++ b/sdncon/__init__.py
@@ -0,0 +1,121 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+import os
+# this line must be before the next imports
+import constants
+SDN_ROOT = constants.SDN_ROOT
+from sdncon.apploader import AppLoader
+from sdncon.urls import urlpatterns
+from django.conf.urls.defaults import *
+from django.http import HttpResponse
+import os.path
+
+coreui_inited = False
+
+ROLE_PATH = "%s/current_role" % SDN_ROOT
+UPGRADE_PATH = "%s/upgrading" % SDN_ROOT
+CASSANDRA_SENTINEL = "%s/run/starting" %SDN_ROOT
+
+SLAVE_RO_URL_WHITELIST = ["/rest/v1/system",
+                       "/rest/v1/controller/storage/tables",
+                       "/rest/v1/model/controller-node",
+                       "/rest/v1/model/controller-alias",
+                       "/rest/v1/model/syncd-config/default",
+                       "/rest/v1/model/feature",
+                       "/rest/v1/model/statdropd-progress-info",
+                       "/rest/v1/model/statdropd-config/default",
+                       "/rest/v1/model/firewall-rule",
+                       "/rest/v1/model/controller-domain-name-server",
+                       "/rest/v1/stats/metadata",
+                       "/rest/v1/system/ha/clustername",
+                       "/rest/v1/system/ha/role",
+                       "/rest/v1/system/reload",
+                       ]
+
+SLAVE_RW_URL_WHITELIST = [
+                         "/rest/v1/stats/data/default",
+                         # Need to make controller-interface RW because the
+                         # discover_ip daemon monitors changes to the network
+                         # interfaces and updates the "discovered_ip" and "mac"
+                         # fields in the controller-interface, even on the slave.
+                         # FIXME: Really those fields should be in a different model so
+                         # we wouldn't be mixing configuration and discovered state,
+                         # but it's too late in the release cycle to make that change.
+                         "/rest/v1/model/controller-interface",
+                         # Needs to be RW, to allow cluster number update
+                         # even if all the controllers are slaves
+                         "/rest/v1/model/global-config",
+                         "/rest/v1/model/firewall-rule",
+                         "/rest/v1/model/controller-node",
+                         "/rest/v1/system/upgrade/image-name",
+                         "/rest/v1/system/upgrade/extract-image-manifest",
+                         "/rest/v1/system/upgrade/execute-upgrade-step",
+                         "/rest/v1/system/upgrade/abort",
+                         "/rest/v1/system/rollback/config",
+                         "/rest/v1/system/ha/decommission",
+                         "/rest/v1/system/ha/role",
+                         "/rest/v1/system/reload",
+                         "/rest/v1/system/resetbsc",
+                         "/rest/v1/system/upload-data",
+                         ]
+
+class SDNConAppLoaderMiddleWare(object):
+    def process_request(self, request):
+        global coreui_inited, urlpatterns
+        if not coreui_inited:
+            try:
+                AppLoader.registerAllApps()
+                coreui_inited = True
+            except Exception, e:
+                print "**** panic! AppLoader.registerAllApps() threw this Exception:"
+                print e
+            for index, app in enumerate(AppLoader.apps):
+                # Redirect / to the first app in the list
+                if (index == 0):
+                    urlpatterns += patterns( '', (r'^$', 'django.views.generic.simple.redirect_to', {'url': '/'+app.name}),)
+                urlpatterns += patterns( '', (r'^'+app.name+'/?$', 'sdncon.coreui.views.show_application_tabs', {'app':app.name}) )
+                urlpatterns += patterns( '', (r'^'+app.name+'/', include(app.name+'.urls')), )
+                for t in app.tabs:
+                    urlpatterns += patterns(app.name+'.views', (r'^'+app.name+'/'+t["id"]+'/?$', t["view"]) )
+
+class HARedirectMiddleWare(object):
+    def process_request (self, request):
+        pinfo = request.path_info
+        if pinfo[-1] == "/" :
+            pinfo = pinfo[:-1]
+
+        if request.method == "GET":
+            for match in SLAVE_RO_URL_WHITELIST:
+                if pinfo.startswith(match):
+                    return None
+
+        for match in SLAVE_RW_URL_WHITELIST:
+            if pinfo.startswith(match):
+                return None
+
+        role = "MASTER"
+        try:
+            with open(ROLE_PATH, "r") as f:
+                for line in f:
+                    if line.startswith("sdnplatform.role"):
+                        role = line.split("=")[1].strip()
+        except IOError, e: # Firstboot doesn't have the file
+            return None
+        if role == "SLAVE" and os.path.exists(UPGRADE_PATH) == False:
+            return HttpResponse(status = 303)
+        else:
+            return None
diff --git a/sdncon/apploader.py b/sdncon/apploader.py
new file mode 100755
index 0000000..5d5db61
--- /dev/null
+++ b/sdncon/apploader.py
@@ -0,0 +1,84 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.db import models
+from django.conf.urls.defaults import *
+
+# This is a class that is used to keep a list of apps and their tabs in memory
+class AppLister():
+    
+    def __init__(self, name, label, priority, description=""):
+        self.name = name
+        self.label = label
+        self.priority = priority
+        self.description = description
+        self.tabs = []
+
+    def orderTabs(self, a, b):
+        return cmp(int(a["priority"]), int(b["priority"]))
+        
+    def addTab(self, id, label, view, priority=1000):
+        for t in self.tabs:
+            if t["id"] == id:
+                self.tabs.remove(t)
+        self.tabs.append( { 'id':id, 'label':label, "priority":priority, "view":view } )
+        self.tabs.sort(self.orderTabs)
+
+class AppLoader():
+    
+    # List of all registered applications
+    #
+    # This is a list of dictionaries
+    #
+    
+    firstInit = True
+    apps = []
+
+    @classmethod    
+    def orderApps(cls, a, b):
+            return cmp(int(a.priority), int(b.priority))
+
+    @classmethod
+    def addApp(cls,app):
+        for a in cls.apps:
+            if a.name == app.name:
+                return False
+        cls.apps.append(app)
+        cls.apps.sort(cls.orderApps)
+            
+    @classmethod
+    def getApps(cls):
+        return cls.apps
+
+    @classmethod    
+    def getApp(cls, name):
+        for a in cls.apps:
+            if a.name == name:
+                return a
+        return None
+        
+    @classmethod
+    def registerAllApps(cls):
+        if cls.firstInit:
+            from django.conf import settings
+            if "sdncon.coreui" not in settings.INSTALLED_APPS:
+                print "****** panic, sdncon.coreui is missing!"
+            for app in settings.INSTALLED_APPS:
+                if not app.startswith("django"):
+                    init_func = __import__("%s.views" % app, fromlist=["bsc_app_init"])
+                    if 'bsc_app_init' in dir(init_func):
+                        init_func.bsc_app_init()
+            cls.firstInit=False
diff --git a/sdncon/apps/cstats/__init__.py b/sdncon/apps/cstats/__init__.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/sdncon/apps/cstats/__init__.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
diff --git a/sdncon/apps/cstats/models.py b/sdncon/apps/cstats/models.py
new file mode 100755
index 0000000..f644f71
--- /dev/null
+++ b/sdncon/apps/cstats/models.py
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.db import models
+
+# Create your models here.
diff --git a/sdncon/apps/cstats/static/css/timeselector.css b/sdncon/apps/cstats/static/css/timeselector.css
new file mode 100755
index 0000000..223ee4e
--- /dev/null
+++ b/sdncon/apps/cstats/static/css/timeselector.css
@@ -0,0 +1,122 @@
+  ul.bsntimeinterval {
+     list-style: none;
+     margin: 2px;
+     padding: 0px;
+     vertical-align: middle;
+     clear: both;
+  }
+  ul.bsntimeinterval li {
+     float: left;
+     margin: 0;
+     padding: 0;
+     height: 30px;
+     display: table;
+     border-spacing: 0px;
+  }
+  .bsntimeinterval div.center {
+     display: table-cell;
+     vertical-align: middle;
+  }
+  .bsntimeinterval a {
+     display: block;
+  }
+  a.bsnselector {
+     cursor: pointer;
+     margin: 0px;
+     padding: 3px;
+     border: solid 1px #333333;
+     border-right: none;
+     color: #2E6E9E;
+     vertical-align: middle;
+
+     background-color: #EEEEEE;
+     /* Firefox 3.6+ */
+     background: -moz-linear-gradient(100% 100% 90deg, #CCCCCC, #EEEEEE);
+     
+     /* Safari 5.1+, Chrome 10+ */
+     background: -webkit-linear-gradient(#EEEEEE, #CCCCCC);
+     
+     /* Opera 11.10+ */
+     background: -o-linear-gradient(#CCCCCC, #EEEEEE);
+
+  }
+  a.bsnselector.left {
+     border-top-left-radius: .5em;
+     border-bottom-left-radius: .5em;
+  }
+  a.bsnselector.right {
+     border-top-right-radius: .5em;
+     border-bottom-right-radius: .5em;
+     border-right: solid 1px #333333;
+  }
+  a.bsnselector:hover {
+     background-color: #DDDDDD;
+
+     /* Firefox 3.6+ */
+     background: -moz-linear-gradient(100% 100% 90deg, #BBBBBB, #DDDDDD);
+     
+     /* Safari 5.1+, Chrome 10+ */
+     background: -webkit-linear-gradient(#DDDDDD, #BBBBBB);
+     
+     /* Opera 11.10+ */
+     background: -o-linear-gradient(#BBBBBB, #DDDDDD);
+  }
+  a.bsnselector.selected {
+     color: #EEEEEE;
+     background-color: #2E6E9E;
+
+     /* Firefox 3.6+ */
+     background: -moz-linear-gradient(100% 100% 90deg, #2E6E9E, #3D92C2);
+     
+     /* Safari 5.1+, Chrome 10+ */
+     background: -webkit-linear-gradient(#3D92C2, #2E6E9E);
+     
+     /* Opera 11.10+ */
+     background: -o-linear-gradient(#2E6E9E, #3D92C2);
+  }
+  .bsnlabel {
+     margin-left: 5px;
+     margin-right: 2px;
+  }
+  .bsnlabel.disabled {
+     color: #BBBBBB;
+  }
+  .bsntimepicker {
+     width: 10em;
+  }
+  .bsncheckbox {
+     vertical-align: middle;
+     margin-left: 5px;
+     margin-right: 0px;
+  }
+  .bsnarrow {
+     cursor: pointer;
+     padding-left: 3px;
+     padding-right: 3px;
+  }
+  .bsnarrow div {
+     width: 0;
+     height: 0;
+  }
+  .bsnarrow.left div {
+     border-top: 11px solid transparent;
+     border-bottom: 11px solid transparent; 
+     border-right:10px solid #CCCCCC;
+  }
+  .bsnarrow.left:hover div {
+     border-right:10px solid #2E6E9E;
+  }
+  .bsnarrow.right div {
+     border-top: 11px solid transparent;
+     border-bottom: 11px solid transparent;
+     border-left: 10px solid #CCCCCC;
+  }
+  .bsnarrow.right:hover div {
+     border-left: 10px solid #2E6E9E;
+  }
+  .bsncheckbox {
+     display: inline;
+  }
+  .clear {
+     clear: both;
+  }
\ No newline at end of file
diff --git a/sdncon/apps/cstats/tests.py b/sdncon/apps/cstats/tests.py
new file mode 100755
index 0000000..793e610
--- /dev/null
+++ b/sdncon/apps/cstats/tests.py
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+"""
+This file demonstrates two different styles of tests (one doctest and one
+unittest). These will both pass when you run "manage.py test".
+
+Replace these with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+class SimpleTest(TestCase):
+    def test_basic_addition(self):
+        """
+        Tests that 1 + 1 always equals 2.
+        """
+        self.failUnlessEqual(1 + 1, 2)
+
+__test__ = {"doctest": """
+Another way to test that 1 + 1 is equal to 2.
+
+>>> 1 + 1 == 2
+True
+"""}
+
diff --git a/sdncon/apps/cstats/urls.py b/sdncon/apps/cstats/urls.py
new file mode 100755
index 0000000..175841f
--- /dev/null
+++ b/sdncon/apps/cstats/urls.py
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.conf.urls.defaults import *
+import os
+
+# Add the URLs that you need here e.g.:
+
+urlpatterns = patterns('',
+#   (r'^tab_mytab/', 'views.mytab'),
+)
+
+# Uncomment this if you have bundeled in static resources (e.g. javascript) or images
+# They will be served from:
+#   app-name/static
+#   app-name/img
+
+urlpatterns += patterns('',
+    (r'^static/(?P<path>.*)$', 'django.views.static.serve', \
+        {'document_root': os.path.join(os.path.dirname(__file__),'static')}),
+#    (r'^img/(?P<path>.*)$', 'django.views.static.serve', \
+#        {'document_root': os.path.join(os.path.dirname(__file__),'img')}),
+)
+
diff --git a/sdncon/apps/cstats/views.py b/sdncon/apps/cstats/views.py
new file mode 100755
index 0000000..eef38dd
--- /dev/null
+++ b/sdncon/apps/cstats/views.py
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+#  Views for the application
+#
+
+from django.shortcuts import render_to_response
+from sdncon.apploader import AppLoader, AppLister
+from sdncon.controller.models import Switch
+import os
+
+def bsc_app_init():  
+    # By default, App Name is the same as directory name. Change if needed.
+    APP_NAME = os.path.dirname(__file__).split("/")[-1]   
+    
+    # Create the App. Parameters are 
+    # - Name: the id, lowercase letters only
+    # - Label: Human readable discription for the menu to the left
+    # - Priority: determines ranking the menu to the left), One-line description
+    # - Description: One line description of the app
+    app = AppLister(APP_NAME, "Controller Stats", 5, "Controller Stats")
+
+    # Add Tabs. Parameters are:
+    # - Name: the id, lowercase letters only
+    # - Label: Human readable discription for the menu to the left
+    # - View: name of the python function that contains the django view (see below)
+    app.addTab("openflow_graphs", "OpenFlow Graphs", flow_graphs_view)
+    app.addTab("system_graphs", "System Graphs", system_stats_graph_view)
+    AppLoader.addApp(app)
+
+def system_stats_graph_view(request):
+    return render_to_response('apps/cstats/templates/graphs.html', {} )
+
+def flow_graphs_view(request):
+    return render_to_response('apps/cstats/templates/openflowgraphs.html', {} )
+
diff --git a/sdncon/apps/docs/__init__.py b/sdncon/apps/docs/__init__.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/sdncon/apps/docs/__init__.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
diff --git a/sdncon/apps/docs/static/pdf/user-guide.pdf b/sdncon/apps/docs/static/pdf/user-guide.pdf
new file mode 100755
index 0000000..af8b537
--- /dev/null
+++ b/sdncon/apps/docs/static/pdf/user-guide.pdf
Binary files differ
diff --git a/sdncon/apps/docs/urls.py b/sdncon/apps/docs/urls.py
new file mode 100755
index 0000000..f345d5f
--- /dev/null
+++ b/sdncon/apps/docs/urls.py
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.conf.urls.defaults import *
+import os
+
+urlpatterns = patterns('docs.views',
+    (r'^user-guide/?$', 'user_guide'),
+)
+
diff --git a/sdncon/apps/docs/views.py b/sdncon/apps/docs/views.py
new file mode 100755
index 0000000..6276736
--- /dev/null
+++ b/sdncon/apps/docs/views.py
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+#  Views for the application
+#
+
+import os
+from django.shortcuts import render_to_response
+from sdncon.apploader import AppLoader, AppLister
+from sdncon.clusterAdmin.utils import isCloudBuild
+
+docs_enabled = False
+
+def bsc_app_init():  
+    if not docs_enabled:
+        return
+
+    APP_NAME = os.path.dirname(__file__).split("/")[-1]   
+    app = AppLister(APP_NAME, "Documentation", 9, "User Guide")
+    app.addTab("docs", "User Guide", user_guide)
+    AppLoader.addApp(app)
+
+def user_guide(request):
+    url = '/docs/static/pdf/user-guide.pdf'
+    return render_to_response('apps/docs/templates/pdf_doc.html', {'url' : url})
diff --git a/sdncon/apps/logs/__init__.py b/sdncon/apps/logs/__init__.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/sdncon/apps/logs/__init__.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
diff --git a/sdncon/apps/logs/models.py b/sdncon/apps/logs/models.py
new file mode 100755
index 0000000..f644f71
--- /dev/null
+++ b/sdncon/apps/logs/models.py
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.db import models
+
+# Create your models here.
diff --git a/sdncon/apps/logs/tests.py b/sdncon/apps/logs/tests.py
new file mode 100755
index 0000000..793e610
--- /dev/null
+++ b/sdncon/apps/logs/tests.py
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+"""
+This file demonstrates two different styles of tests (one doctest and one
+unittest). These will both pass when you run "manage.py test".
+
+Replace these with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+class SimpleTest(TestCase):
+    def test_basic_addition(self):
+        """
+        Tests that 1 + 1 always equals 2.
+        """
+        self.failUnlessEqual(1 + 1, 2)
+
+__test__ = {"doctest": """
+Another way to test that 1 + 1 is equal to 2.
+
+>>> 1 + 1 == 2
+True
+"""}
+
diff --git a/sdncon/apps/logs/urls.py b/sdncon/apps/logs/urls.py
new file mode 100755
index 0000000..0ba1f5f
--- /dev/null
+++ b/sdncon/apps/logs/urls.py
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.conf.urls.defaults import *
+import os
+
+# Add the URLs that you need here e.g.:
+
+urlpatterns = patterns('',
+#   (r'^tab_mytab/', 'views.mytab'),
+)
+
+# Uncomment this if you have bundeled in static resources (e.g. javascript) or images
+# They will be served from:
+#   app-name/static
+#   app-name/img
+
+urlpatterns += patterns('',
+    (r'^static/(?P<path>.*)$', 'django.views.static.serve', \
+        {'document_root': os.path.join(os.path.dirname(__file__),'static')}),
+#    (r'^img/(?P<path>.*)$', 'django.views.static.serve', \
+#        {'document_root': os.path.join(os.path.dirname(__file__),'img')}),
+)
+
+urlpatterns += patterns('logs.views',
+(r'^rest/v1/controller-log-data-all/(?P<cluster>[A-Za-z0-9_:.\-]+)/(?P<controller>[A-Za-z0-9_\.\-]+)/?$', 'controller_log_data_all'),
+(r'^rest/v1/controller-log-data-controller/(?P<cluster>[A-Za-z0-9_:.\-]+)/(?P<controller>[A-Za-z0-9_\.\-]+)/?$', 'controller_log_data_controller'),
+(r'^rest/v1/controller-log-data-db/(?P<cluster>[A-Za-z0-9_:.\-]+)/(?P<controller>[A-Za-z0-9_\.\-]+)/?$', 'controller_log_data_db'),
+(r'^rest/v1/controller-log-data-sdncon/(?P<cluster>[A-Za-z0-9_:.\-]+)/(?P<controller>[A-Za-z0-9_\.\-]+)/?$', 'controller_log_data_sdncon'),
+)
+
diff --git a/sdncon/apps/logs/views.py b/sdncon/apps/logs/views.py
new file mode 100755
index 0000000..4018f90
--- /dev/null
+++ b/sdncon/apps/logs/views.py
@@ -0,0 +1,231 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+#  Views for the application
+#
+
+from django.http import HttpResponse
+from django.shortcuts import render_to_response
+from django.utils import simplejson
+from sdncon.rest.jsonview import JsonResponse
+from sdncon.apploader import AppLoader, AppLister
+from sdncon.stats.views import init_db_connection
+from sdncon.stats.data import get_log_event_data
+import os
+import time
+import sdncon
+
+ComponentXlation = {
+    'cassandra': 'database',
+    'sdncon': 'sdncon',
+    'sdnplatform': 'controller'
+}
+
+def log_collection_enabled(config_file="%s/statd/statd.conf" % sdncon.SDN_ROOT):
+    import json
+    enabled = False
+    try:
+        with open(config_file, 'r') as fp:
+            conf = json.load(fp)
+            if conf.get('input'):
+                for i in conf['input']:
+                    if i.get('name') == 'LogCollector' and i.get('modules'):
+                        enabled = True
+                        break;
+    except:
+        pass
+    return enabled
+
+def bsc_app_init():
+    # Check if logging is enabled, else do not start the app
+    if not log_collection_enabled():
+        return
+
+    # By default, App Name is the same as directory name. Change if needed.
+    APP_NAME = os.path.dirname(__file__).split("/")[-1]   
+    
+    # Create the App. Parameters are 
+    # - Name: the id, lowercase letters only
+    # - Label: Human readable discription for the menu to the left
+    # - Priority: determines ranking the menu to the left), One-line description
+    # - Description: One line description of the app
+    app = AppLister(APP_NAME, "Logs", 5, "Controller Logs")
+
+    # Add Tabs. Parameters are:
+    # - Name: the id, lowercase letters only
+    # - Label: Human readable discription for the menu to the left
+    # - View: name of the python function that contains the django view (see below)
+    app.addTab("controllerlogs", "Controller Logs", controller)
+    app.addTab("dblogs", "Database Logs", db)
+    app.addTab("sdnconlogs", "SDNCon Logs", sdncon)
+    app.addTab("alllogs", "All Logs", all)
+    AppLoader.addApp(app)
+
+# Views - functions that serve the HTML that goes into each tab
+def controller(request):
+    return render_to_response('apps/logs/templates/logs.html', { 'source' : 'controller' } )
+
+def db(request):
+    return render_to_response('apps/logs/templates/logs.html', { 'source' : 'db' } )
+
+def sdncon(request):
+    return render_to_response('apps/logs/templates/logs.html', { 'source' : 'sdncon' } )
+
+def all(request):
+    return render_to_response('apps/logs/templates/logs.html', { 'source' : 'all' } )
+
+# Views defined in urls.py
+def controller_log_data_all(request, cluster, controller):
+    init_db_connection()
+    time_now = time.time()*1000 #conver to ms
+    # we only get one day for now, this will be fixed when we move to an actually scalable solution
+    data_dict = get_log_event_data(cluster, controller, time_now - 86400000, time_now)
+    arr = get_array_from_dict(data_dict, True)
+    return generic_server_side_datatable(request, arr)
+
+def controller_log_data_controller(request, cluster, controller):
+    init_db_connection()
+    time_now = time.time()*1000 #conver to ms
+    # we only get one day for now, this will be fixed when we move to an actually scalable solution
+    data_dict = get_log_event_data(cluster, controller, time_now - 86400000, time_now)
+    filtered_dict = []
+    for e in data_dict:
+        if e['component'] == 'sdnplatform' or e['component'] == 'sdnplatform.request':
+            filtered_dict.append(e)
+    arr = get_array_from_dict(filtered_dict, False)
+    return generic_server_side_datatable(request, arr)
+
+def controller_log_data_db(request, cluster, controller):
+    init_db_connection()
+    time_now = time.time()*1000 #conver to ms
+    # we only get one day for now, this will be fixed when we move to an actually scalable solution
+    data_dict = get_log_event_data(cluster, controller, time_now - 86400000, time_now)
+    filtered_dict = []
+    for e in data_dict:
+        if e['component'] == 'cassandra':
+            filtered_dict.append(e)
+    arr = get_array_from_dict(filtered_dict, False)
+    return generic_server_side_datatable(request, arr)
+
+def controller_log_data_sdncon(request, cluster, controller):
+    init_db_connection()
+    time_now = time.time()*1000 #conver to ms
+    # we only get one day for now, this will be fixed when we move to an actually scalable solution
+    data_dict = get_log_event_data(cluster, controller, time_now - 86400000, time_now)
+    filtered_dict = []
+    for e in data_dict:
+        if e['component'] == 'sdncon':
+            filtered_dict.append(e)
+    arr = get_array_from_dict(filtered_dict, False)
+    return generic_server_side_datatable(request, arr)
+
+
+# Helper functions
+def generic_server_side_datatable(request, data_array): 
+    start   = request.GET.get("iDisplayStart",0)
+    length  = request.GET.get("iDisplayLength",10)
+    search_str  = request.GET.get("sSearch",None)
+    
+    if search_str:
+        data_array_f = []
+        for d in data_array:
+            for e in d:
+                try:
+                    if e.find(search_str) > -1:
+                        data_array_f.append(d)
+                        break
+                except Exception:
+                    pass
+    else:
+        data_array_f = data_array
+
+    data_subset = data_array_f[int(start):int(start)+int(length)]
+    response_data = '{ "aaData":'+simplejson.dumps(data_subset) + ', "iTotalDisplayRecords": ' + str(len(data_array_f)) + ', "iTotalRecords": ' + str(len(data_array_f)) +'}'
+    return HttpResponse(response_data, 'application/json')
+
+# Takes a dictionary that includes 
+# { "timestamp": unix_ts, "level" : "string", "message": "msg" }
+# and turns it into a 2D array that includes
+# [ [unix_ts, level, message], [etc], [etc] ] 
+def get_array_from_dict(dict, includeComp):
+    array = []
+    for element in reversed(dict):
+        if 'component' in element and element['component'] == 'sdnplatform.request':
+            entry = parse_sdnplatform_request_log_entry(element)
+        else:
+            entry = []
+            if 'timestamp' in element:
+                entry.append(element['timestamp'])
+            else:
+                entry.append('-')
+            if 'log-level' in element:
+                entry.append(element['log-level'])
+            else:
+                entry.append('-')
+            if 'message' in element:
+                entry.append(element['message'])
+            else:
+                entry.append('-')
+
+        if includeComp:
+            if 'component' in element:
+                entry.insert(1, ComponentXlation[element['component']])
+            else:
+                entry.append(1, '-')
+
+        array.append(entry)
+    return array
+
+# Parses a SDNPlatform request log entry into an array
+# Format is similar to
+# {
+#   'package': 'Python-urllib/2.7', 
+#   'timestamp': 1306967011000L, 
+#   'component': 'sdnplatform.request', 
+#   'request': 'GET /wm/core/counter/00:00:00:00:00:73:28:02_OFPacketIn_L3_IPv4/json HTTP/1.1', 
+#   'responseLen': '37', 
+#   'client': '127.0.0.1', 
+#   'responseCode': '200'
+# }
+# Output array is [unix_ts, level, message]
+def parse_sdnplatform_request_log_entry(element):
+    entry = []
+    if 'timestamp' in element:
+        entry.append(element['timestamp'])
+    else:
+        entry.append('-')
+    if 'responseCode' in element:
+        rc = element['responseCode']
+        if rc == '404' or rc == '500':
+            entry.append('ERROR')
+        elif rc == '200':
+            entry.append('INFO')
+        else:
+            entry.append('-')
+    else:
+        entry.append('-')
+    msg = ''
+    if 'request' in element:
+        msg += element['request']
+    if 'client' in element:
+        msg += ' CLIENT ' + element['client']
+    if 'responseCode' in element:
+        msg += ' ' + element['responseCode']
+    if 'package' in element:
+        msg += ' ' + element['package']
+    entry.append(msg)
+    return entry
+
diff --git a/sdncon/clusterAdmin/__init__.py b/sdncon/clusterAdmin/__init__.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/sdncon/clusterAdmin/__init__.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
diff --git a/sdncon/clusterAdmin/admin.py b/sdncon/clusterAdmin/admin.py
new file mode 100755
index 0000000..2a4a993
--- /dev/null
+++ b/sdncon/clusterAdmin/admin.py
@@ -0,0 +1,22 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from sdncon.clusterAdmin.models import Customer, Cluster, CustomerUser
+from django.contrib import admin
+
+admin.site.register(Customer)
+admin.site.register(Cluster)
+admin.site.register(CustomerUser)
diff --git a/sdncon/clusterAdmin/middleware.py b/sdncon/clusterAdmin/middleware.py
new file mode 100755
index 0000000..f66b367
--- /dev/null
+++ b/sdncon/clusterAdmin/middleware.py
@@ -0,0 +1,269 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+import sys, re
+from django.conf import settings
+from django.contrib.auth.views import login
+from django.http import HttpResponseRedirect, HttpResponse
+from django.utils import simplejson
+from django.contrib import auth
+from django.contrib.auth.models import User, AnonymousUser
+
+from .utils import isCloudBuild
+from .models import CustomerUser, Customer, Cluster, AuthToken
+
+import logging
+debugLevel = logging.INFO
+logfile = None
+
+# For testing, uncomment as required
+#debugLevel = logging.DEBUG
+#logfile = 'middleware.log'
+
+def initLogger():
+    logger = logging.getLogger('middleware')
+    formatter = logging.Formatter('%(asctime)s [%(name)s] %(levelname)s %(message)s')
+    logger.setLevel(debugLevel)
+
+    # Add a file handler
+    if logfile:
+        file_handler = logging.FileHandler(logfile)
+        file_handler.setFormatter(formatter)
+        logger.addHandler(file_handler)
+
+    # Add a console handler
+    console_handler = logging.StreamHandler()
+    console_handler.setFormatter(formatter)
+    console_handler.setLevel(debugLevel)
+    logger.addHandler(console_handler)
+    return logger
+
+logger = initLogger()
+
+def is_localhost(request):
+    return request.META['REMOTE_ADDR'] in ['127.0.0.1', '127.0.1.1', 'localhost']
+
+class RequireAuthMiddleware(object):
+    """RequireAuthMiddleware: Middleware to enforce authentication
+
+    If it is enabled, every Django-powered page, except LOGIN_URL and the list of EXEMPT_URLS,
+    will require authentication
+
+    Unautenticated user requests are redirected to the login page set (LOGIN_URL in settings)
+    Unautenticated REST calls which are returned a JSON error as a 403 forbidden response
+    """
+    
+    def __init__(self):
+        self.enforce_auth = isCloudBuild() # For now, enforce authentication only if we are a cloud instance
+        self.login_url = getattr(settings, 'LOGIN_URL', '/accounts/login/')
+        self.exempt_urls = [self.login_url]
+        self.exempt_urls += getattr(settings, 'EXEMPT_URLS', [] )
+        self.rest_prefix = getattr(settings, 'REST_PREFIX', '/rest/')
+        if self.enforce_auth:
+            logger.info('RequireAuthMiddleware: Enforcing Authentication')
+    
+    def process_request(self, request):
+        if self.enforce_auth:
+            if is_localhost(request):
+                return None
+            if request.user.is_anonymous():
+                for url in self.exempt_urls:
+                    if request.path.startswith(url):
+                        return None
+                return self.redirect(request)
+        return None
+
+    def process_response(self, request, response):
+        if request.path.startswith(self.login_url):
+            response['x-bsc-auth-status'] = 'required'
+        return response    
+
+    def redirect(self, request):
+        if self.rest_prefix in request.path:
+            logger.warn('RequireAuthMiddleware: Unauthenticated REST request: %s, %s, %s' % (
+                request.path, str(request.user), request.META['REMOTE_ADDR']))
+            json_content_type = 'application/json'
+            json_error_response = {'error_type': 'auth', 'description': 'Authentication error'}
+            return HttpResponse(simplejson.dumps(json_error_response), json_content_type, 403)
+
+        logger.debug('RequireAuthMiddleware: Redirecting to login page: %s, %s, %s' % (
+            request.path, str(request.user), request.META['REMOTE_ADDR']))
+        return HttpResponseRedirect('%s?next=%s' % (self.login_url, request.path))
+
+
+class ClusterAuthenticate(object):
+    """ClusterAuthenticate: Middleware that authenticates/sets credentials for the REST requests
+
+    If this is a REST request:
+        If request is from localhost
+            authorize it and set the user as admin
+        If a the user already has an authenticated session
+            validate that this user is authorized to access the requested cluster
+        If it is from an anonynous user:
+            extract auth token from the request parameters and
+            verify that the token is in authorized for the requested cluster
+            (for now, just validate that the user associated with the token
+             is authorized to access the requested cluster. In future, we may do more)
+    """
+
+    token_param_name = 'auth-token'     # Name of the auth token parameter in the query string
+    enforce_auth = isCloudBuild()       # For now, enfore auth only for the cloud instance
+    bypass_localhost_check = False      # Set to true to force auth token check even on localhost
+
+    def process_request(self, request):
+        logger.debug('url: ' + request.path)
+        if not self.enforce_auth:
+            logger.debug('ClusterAuthenticate ignored: is disabled')
+            return
+        if is_localhost(request) and not self.bypass_localhost_check:
+            logger.debug('ClusterAuthenticate ignored: is local request')
+            return
+        if self.get_req_cluster_name(request) is None:
+            logger.debug('ClusterAuthenticate ignored: no cluster name in request');
+            return
+
+        # Find user and autorized clusters
+        cluster_name = self.get_req_cluster_name(request)
+        cluster = self.get_cluster_from_name(cluster_name)
+        user = AnonymousUser()
+        if hasattr(request, 'session'):
+            user = auth.get_user(request)
+            logger.debug('User from request: ' + str(user))
+        if user.is_authenticated():
+            allowed_clusters = self.get_allowed_clusters_for_user(user)
+        else:
+            token_string = self.get_req_token_string(request)
+            user = self.get_user_for_token(token_string)
+            allowed_clusters = self.get_allowed_clusters_for_token(token_string)
+        logger.debug('Checking authorization for cluster ' + str(cluster) +
+                     ' in cluster list ' + str(allowed_clusters) +
+                     ' for ' + str(user))
+
+        # Do validation/set user for request
+        if hasattr(request, 'user'):
+            request.user = AnonymousUser()
+            request._cached_user = AnonymousUser()
+        if cluster and allowed_clusters:
+            if cluster in allowed_clusters:
+                request.user = user
+                request._cached_user = user
+        return
+
+    def validate_session(self, request):
+        return True
+
+    def get_req_cluster_name(self, request):
+        # Find last entry in path, remove parameters
+        path = request.path
+        cluster_name = None
+        try:
+            pathcomps = path.split('/')
+            if 'rest' in (pathcomps[1],pathcomps[2]):
+                cluster_name_idx = 5
+                if pathcomps[cluster_name_idx].find(':') > -1:
+                    cluster_name = pathcomps[cluster_name_idx]
+        except (TypeError, IndexError):
+            logger.debug('Type error parsing path for customer: ' + str(path))
+            return None
+        except Exception:
+            logger.debug('Unknown error parsing path for customer: ' + str(path))
+            return None
+        return cluster_name
+
+    def get_cluster_from_name(self, cluster_name):
+        if cluster_name:
+            for cluster in Cluster.objects.all():
+                if cluster_name == cluster.id:
+                    logger.debug('Mapped request to cluster "%s"' % cluster_name)
+                    return cluster
+        logger.warn('Failed to map request to cluster: "%s"' % cluster_name)
+        return None
+
+    def get_req_token_string(self, request):
+        token_string = None
+        try:
+            token_string = request.REQUEST[self.token_param_name]
+            token_string = token_string.upper()
+        except KeyError:
+            logger.debug('No token param in request')
+        return token_string
+
+    def get_token_from_name(self, token_string):
+        token = None
+        if token_string:
+            try:
+                token = AuthToken.objects.get(id=token_string)
+            except AuthToken.DoesNotExist:
+                logger.debug('Token not found in DB: ' + str(token_string))
+                token = None
+            except Exception:
+                logger.debug('Auth Tokens not configured in DB? - ' + str(token_string))
+                token = None
+        return token
+
+    def get_user_for_token(self, token_string):
+        user = AnonymousUser()
+        token = self.get_token_from_name(token_string)
+        if token:
+            user = token.user
+        return user
+
+    def get_allowed_clusters_for_token(self, token_string):
+        """Given an auth token, generate the list of clusters for which it gives credentials
+
+        If the cluster entry in the token object is present, use that
+        If the customer entry in the token object is present, return all clusters for the customer
+        If the user entry in the token object is present, use that to get a list of clusters.
+
+        In the future, DB changes may provide varying granularity.
+        """
+
+        logger.debug('Got token: ' + str(token_string))
+
+        cluster_list = []
+        token = self.get_token_from_name(token_string)
+        if token:
+            if token.cluster is not None:
+                logger.debug('token mapped to cluster ' + str(token.cluster))
+                cluster_list = [token.cluster]
+            elif token.customer is not None:
+                logger.debug('token mapped to customer ' + str(token.customer))
+                cluster_list = Cluster.objects.filter(customer=token.customer)
+            else:
+                logger.debug('token mapped to user ' + str(token.user))
+                cluster_list = self.get_allowed_clusters_for_user(token.user)
+
+        logger.debug('Returning clust list ' + str(cluster_list))
+        return cluster_list
+
+    def get_allowed_clusters_for_user(self, user):
+        """Given a user, generate the list of clusters for which it gives credentials
+        Use user to map to a customer (list) and from there to a list of clusters.
+        """
+
+        logger.debug('Got user: ' + str(user))
+
+        cluster_list = []
+        if user:
+            for cust_user in CustomerUser.objects.filter(user=user):
+                # Currently the query below isn't working.  Brute force alternative given
+                #cluster_list.extend(Cluster.objects.filter(customer=cust_user.customer))
+                for cluster in Cluster.objects.all():
+                    if cluster.customer == cust_user.customer:
+                        cluster_list.append(cluster)
+
+        logger.debug('Returning cluster list ' + str(cluster_list))
+        return cluster_list
diff --git a/sdncon/clusterAdmin/models.py b/sdncon/clusterAdmin/models.py
new file mode 100755
index 0000000..9090fb6
--- /dev/null
+++ b/sdncon/clusterAdmin/models.py
@@ -0,0 +1,170 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+import datetime
+from django.db import models
+from django.contrib.auth.models import User
+
+# Create your models here.
+class CustomerManager(models.Manager):
+
+    def create_customer(self, name, email):
+        """
+        Creates and saves a customer with the given name and email
+        """
+        now = datetime.datetime.now()
+
+        # Normalize the address by lowercasing the domain part of the email address
+        try:
+            email_name, domain_part = email.strip().split('@', 1)
+        except ValueError:
+            pass
+        else:
+            email = '@'.join([email_name, domain_part.lower()])
+
+        customer = self.model(customername=name, is_active=True, date_joined=now)
+        customer.save(using=self._db)
+        return customer
+
+class ClusterManager(models.Manager):
+
+    def create_cluster(self, name, customer):
+        """
+        Creates and saves a cluster with the given cluster name and the customer
+        """
+        print "clusterManager create_cluster"
+        now = datetime.datetime.now()
+
+        id = ":".join([customer.customername, name])
+        cluster = self.model(id=id, clustername=name, is_active=True, date_joined=now)
+        cluster.save(using=self._db)
+        return cluster
+
+class CustomerUserManager(models.Manager):
+
+    def create_customerUser(self, user, customer):
+        """
+        Creates and saves a customer user membership
+        """
+        id = ":".join([customer.customername, user.username])
+        cu = self.model(id=id, user=user, customer=customer)
+        cu.save(using=self._db)
+        return cu
+
+class Customer(models.Model):
+    """
+    Customer defines a customer in the cloud server.
+    """
+    customername = models.CharField('customer name', 
+                    primary_key=True,
+                    max_length=30, 
+                    help_text="30 characters or fewer. Letters, numbers and @/./+/-/_ characters")
+    email = models.EmailField('e-mail address', blank=True)
+    is_active = models.BooleanField('active', 
+                    default=True, 
+                    help_text="Designates whether this Customer should be treated as active. Unselect this instead of deleting accounts.")
+    date_joined = models.DateTimeField('date joined', default=datetime.datetime.now)
+    objects = CustomerManager()
+
+    def __unicode__(self):
+        return self.customername
+
+class Cluster(models.Model):
+    """
+    Cluster defines a cluster of nodes in the cloud server.
+    """
+    id = models.CharField(
+                primary_key=True,
+                verbose_name='Cluster ID',
+                max_length=75,
+                help_text='Unique identifier for the cluster; format is customername:clustername')
+    clustername = models.CharField('cluster name', 
+                    max_length=30, 
+                    help_text="Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters")
+    is_active = models.BooleanField('active', 
+                    default=True, 
+                    help_text="Designates whether this cluster should be treated as active. Unselect this instead of deleting the cluster.")
+    date_joined = models.DateTimeField('date joined', 
+                    default=datetime.datetime.now)
+
+    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
+
+    objects = ClusterManager()
+
+    def __unicode__(self):
+        return self.id
+
+
+class CustomerUser(models.Model):
+    """
+    This is a temporary model that captures the list of users in a given customer
+    """
+    id = models.CharField(
+                primary_key=True,
+                verbose_name='Customer User',
+                max_length=75,
+                help_text='Unique relationship that shows the customer which the user belongs; \
+                    format is customername:username')
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
+    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
+
+    objects = CustomerUserManager()
+
+    def __unicode__(self):
+        return self.id
+
+
+class AuthToken(models.Model):
+    """
+    Store the authentication token as an ascii string
+    Associate various credential options: user, cluster, customer.  At least
+    one of these must be populated to be a valid entry.
+    """
+    id = models.CharField(
+        primary_key=True,
+        max_length = 64)
+
+    cluster = models.ForeignKey(
+        Cluster,
+        blank=True,
+        null=True)
+
+    user = models.ForeignKey(
+        User,
+        blank=True,
+        null=True)
+
+    customer = models.ForeignKey(
+        Customer,
+        blank=True,
+        null=True)
+
+    expiration_date = models.DateTimeField(
+        verbose_name='Expiration Date',
+        help_text='Date when the authentication token expires',
+        blank=True,
+        null=True)
+
+    annotation = models.CharField(
+        verbose_name='Annotation',
+        help_text='Track creation information such as user',
+        max_length=512,
+        blank=True,
+        null=True)
+
+    def __unicode__(self):
+        return str(self.id)
+
diff --git a/sdncon/clusterAdmin/tests.py b/sdncon/clusterAdmin/tests.py
new file mode 100755
index 0000000..793e610
--- /dev/null
+++ b/sdncon/clusterAdmin/tests.py
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+"""
+This file demonstrates two different styles of tests (one doctest and one
+unittest). These will both pass when you run "manage.py test".
+
+Replace these with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+class SimpleTest(TestCase):
+    def test_basic_addition(self):
+        """
+        Tests that 1 + 1 always equals 2.
+        """
+        self.failUnlessEqual(1 + 1, 2)
+
+__test__ = {"doctest": """
+Another way to test that 1 + 1 is equal to 2.
+
+>>> 1 + 1 == 2
+True
+"""}
+
diff --git a/sdncon/clusterAdmin/tests/__init__.py b/sdncon/clusterAdmin/tests/__init__.py
new file mode 100755
index 0000000..cdc3d76
--- /dev/null
+++ b/sdncon/clusterAdmin/tests/__init__.py
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+#from django.contrib.auth.tests.auth_backends import BackendTest, RowlevelBackendTest, AnonymousUserBackendTest, NoAnonymousUserBackendTest
+
+from django.contrib.auth.tests.basic import BasicTestCase
+from django.contrib.auth.tests.decorators import LoginRequiredTestCase
+#from django.contrib.auth.tests.forms import UserCreationFormTest, AuthenticationFormTest, SetPasswordFormTest, PasswordChangeFormTest, UserChangeFormTest, PasswordResetFormTest
+from django.contrib.auth.tests.remote_user \
+        import RemoteUserTest, RemoteUserNoCreateTest, RemoteUserCustomTest
+from django.contrib.auth.tests.models import ProfileTestCase
+from django.contrib.auth.tests.tokens import TokenGeneratorTest
+#from django.contrib.auth.tests.views \
+#    import PasswordResetTest, ChangePasswordTest, LoginTest, LogoutTest
+
+
+from sdncon.clusterAdmin.tests.auth_backends import BackendTest, RowlevelBackendTest, AnonymousUserBackendTest, NoAnonymousUserBackendTest
+from sdncon.clusterAdmin.tests.forms import UserCreationFormTest, AuthenticationFormTest, SetPasswordFormTest, PasswordChangeFormTest, UserChangeFormTest, PasswordResetFormTest
+from sdncon.clusterAdmin.tests.views \
+        import PasswordResetTest, ChangePasswordTest, LoginTest, LogoutTest
+
+# The password for the fixture data users is 'password'
diff --git a/sdncon/clusterAdmin/tests/auth_backends.py b/sdncon/clusterAdmin/tests/auth_backends.py
new file mode 100755
index 0000000..ce26859
--- /dev/null
+++ b/sdncon/clusterAdmin/tests/auth_backends.py
@@ -0,0 +1,280 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+import warnings
+
+from django.conf import settings
+from django.contrib.auth.models import User, Group, Permission, AnonymousUser
+from django.contrib.contenttypes.models import ContentType
+from django.test import TestCase
+from django.utils.unittest import skipIf
+
+
+class BackendTest(TestCase):
+
+    backend = 'django.contrib.auth.backends.ModelBackend'
+
+    def setUp(self):
+        self.curr_auth = settings.AUTHENTICATION_BACKENDS
+        settings.AUTHENTICATION_BACKENDS = (self.backend,)
+        User.objects.create_user('test', 'test@example.com', 'test')
+
+    def tearDown(self):
+        settings.AUTHENTICATION_BACKENDS = self.curr_auth
+
+    @skipIf(True, "Do not support")
+    def test_has_perm(self):
+        user = User.objects.get(username='test')
+        self.assertEqual(user.has_perm('auth.test'), False)
+        user.is_staff = True
+        user.save()
+        self.assertEqual(user.has_perm('auth.test'), False)
+        user.is_superuser = True
+        user.save()
+        self.assertEqual(user.has_perm('auth.test'), True)
+        user.is_staff = False
+        user.is_superuser = False
+        user.save()
+        self.assertEqual(user.has_perm('auth.test'), False)
+        user.is_staff = True
+        user.is_superuser = True
+        user.is_active = False
+        user.save()
+        self.assertEqual(user.has_perm('auth.test'), False)
+
+    @skipIf(True, "Do not support")
+    def test_custom_perms(self):
+        user = User.objects.get(username='test')
+        content_type=ContentType.objects.get_for_model(Group)
+        perm = Permission.objects.create(name='test', content_type=content_type, codename='test')
+        user.user_permissions.add(perm)
+        user.save()
+
+        # reloading user to purge the _perm_cache
+        user = User.objects.get(username='test')
+        self.assertEqual(user.get_all_permissions() == set([u'auth.test']), True)
+        self.assertEqual(user.get_group_permissions(), set([]))
+        self.assertEqual(user.has_module_perms('Group'), False)
+        self.assertEqual(user.has_module_perms('auth'), True)
+        perm = Permission.objects.create(name='test2', content_type=content_type, codename='test2')
+        user.user_permissions.add(perm)
+        user.save()
+        perm = Permission.objects.create(name='test3', content_type=content_type, codename='test3')
+        user.user_permissions.add(perm)
+        user.save()
+        user = User.objects.get(username='test')
+        self.assertEqual(user.get_all_permissions(), set([u'auth.test2', u'auth.test', u'auth.test3']))
+        self.assertEqual(user.has_perm('test'), False)
+        self.assertEqual(user.has_perm('auth.test'), True)
+        self.assertEqual(user.has_perms(['auth.test2', 'auth.test3']), True)
+        perm = Permission.objects.create(name='test_group', content_type=content_type, codename='test_group')
+        group = Group.objects.create(name='test_group')
+        group.permissions.add(perm)
+        group.save()
+        user.groups.add(group)
+        user = User.objects.get(username='test')
+        exp = set([u'auth.test2', u'auth.test', u'auth.test3', u'auth.test_group'])
+        self.assertEqual(user.get_all_permissions(), exp)
+        self.assertEqual(user.get_group_permissions(), set([u'auth.test_group']))
+        self.assertEqual(user.has_perms(['auth.test3', 'auth.test_group']), True)
+
+        user = AnonymousUser()
+        self.assertEqual(user.has_perm('test'), False)
+        self.assertEqual(user.has_perms(['auth.test2', 'auth.test3']), False)
+
+    @skipIf(True, "Do not support")
+    def test_has_no_object_perm(self):
+        """Regressiontest for #12462"""
+        user = User.objects.get(username='test')
+        content_type=ContentType.objects.get_for_model(Group)
+        perm = Permission.objects.create(name='test', content_type=content_type, codename='test')
+        user.user_permissions.add(perm)
+        user.save()
+
+        self.assertEqual(user.has_perm('auth.test', 'object'), False)
+        self.assertEqual(user.get_all_permissions('object'), set([]))
+        self.assertEqual(user.has_perm('auth.test'), True)
+        self.assertEqual(user.get_all_permissions(), set(['auth.test']))
+
+
+class TestObj(object):
+    pass
+
+
+class SimpleRowlevelBackend(object):
+    supports_object_permissions = True
+
+    # This class also supports tests for anonymous user permissions,
+    # via subclasses which just set the 'supports_anonymous_user' attribute.
+
+    def has_perm(self, user, perm, obj=None):
+        if not obj:
+            return # We only support row level perms
+
+        if isinstance(obj, TestObj):
+            if user.username == 'test2':
+                return True
+            elif user.is_anonymous() and perm == 'anon':
+                # not reached due to supports_anonymous_user = False
+                return True
+        return False
+
+    def has_module_perms(self, user, app_label):
+        return app_label == "app1"
+
+    def get_all_permissions(self, user, obj=None):
+        if not obj:
+            return [] # We only support row level perms
+
+        if not isinstance(obj, TestObj):
+            return ['none']
+
+        if user.is_anonymous():
+            return ['anon']
+        if user.username == 'test2':
+            return ['simple', 'advanced']
+        else:
+            return ['simple']
+
+    def get_group_permissions(self, user, obj=None):
+        if not obj:
+            return # We only support row level perms
+
+        if not isinstance(obj, TestObj):
+            return ['none']
+
+        if 'test_group' in [group.name for group in user.groups.all()]:
+            return ['group_perm']
+        else:
+            return ['none']
+
+
+class RowlevelBackendTest(TestCase):
+    """
+    Tests for auth backend that supports object level permissions
+    """
+    backend = 'django.contrib.auth.tests.auth_backends.SimpleRowlevelBackend'
+
+    def setUp(self):
+        self.curr_auth = settings.AUTHENTICATION_BACKENDS
+        settings.AUTHENTICATION_BACKENDS = tuple(self.curr_auth) + (self.backend,)
+        self.user1 = User.objects.create_user('test', 'test@example.com', 'test')
+        self.user2 = User.objects.create_user('test2', 'test2@example.com', 'test')
+        self.user3 = User.objects.create_user('test3', 'test3@example.com', 'test')
+        self.save_warnings_state()
+        warnings.filterwarnings('ignore', category=DeprecationWarning,
+                                module='django.contrib.auth')
+
+    def tearDown(self):
+        settings.AUTHENTICATION_BACKENDS = self.curr_auth
+        self.restore_warnings_state()
+
+    @skipIf(True, "Do not support")
+    def test_has_perm(self):
+        self.assertEqual(self.user1.has_perm('perm', TestObj()), False)
+        self.assertEqual(self.user2.has_perm('perm', TestObj()), True)
+        self.assertEqual(self.user2.has_perm('perm'), False)
+        self.assertEqual(self.user2.has_perms(['simple', 'advanced'], TestObj()), True)
+        self.assertEqual(self.user3.has_perm('perm', TestObj()), False)
+        self.assertEqual(self.user3.has_perm('anon', TestObj()), False)
+        self.assertEqual(self.user3.has_perms(['simple', 'advanced'], TestObj()), False)
+
+    @skipIf(True, "Do not support")
+    def test_get_all_permissions(self):
+        self.assertEqual(self.user1.get_all_permissions(TestObj()), set(['simple']))
+        self.assertEqual(self.user2.get_all_permissions(TestObj()), set(['simple', 'advanced']))
+        self.assertEqual(self.user2.get_all_permissions(), set([]))
+
+    @skipIf(True, "Do not support")
+    def test_get_group_permissions(self):
+        content_type=ContentType.objects.get_for_model(Group)
+        group = Group.objects.create(name='test_group')
+        self.user3.groups.add(group)
+        self.assertEqual(self.user3.get_group_permissions(TestObj()), set(['group_perm']))
+
+
+class AnonymousUserBackend(SimpleRowlevelBackend):
+
+    supports_anonymous_user = True
+
+
+class NoAnonymousUserBackend(SimpleRowlevelBackend):
+
+    supports_anonymous_user = False
+
+
+class AnonymousUserBackendTest(TestCase):
+    """
+    Tests for AnonymousUser delegating to backend if it has 'supports_anonymous_user' = True
+    """
+
+    backend = 'django.contrib.auth.tests.auth_backends.AnonymousUserBackend'
+
+    def setUp(self):
+        self.curr_auth = settings.AUTHENTICATION_BACKENDS
+        settings.AUTHENTICATION_BACKENDS = (self.backend,)
+        self.user1 = AnonymousUser()
+
+    def tearDown(self):
+        settings.AUTHENTICATION_BACKENDS = self.curr_auth
+
+    @skipIf(True, "Do not support")
+    def test_has_perm(self):
+        self.assertEqual(self.user1.has_perm('perm', TestObj()), False)
+        self.assertEqual(self.user1.has_perm('anon', TestObj()), True)
+
+    @skipIf(True, "Do not support")
+    def test_has_perms(self):
+        self.assertEqual(self.user1.has_perms(['anon'], TestObj()), True)
+        self.assertEqual(self.user1.has_perms(['anon', 'perm'], TestObj()), False)
+
+    def test_has_module_perms(self):
+        self.assertEqual(self.user1.has_module_perms("app1"), True)
+        self.assertEqual(self.user1.has_module_perms("app2"), False)
+
+    @skipIf(True, "Do not support")
+    def test_get_all_permissions(self):
+        self.assertEqual(self.user1.get_all_permissions(TestObj()), set(['anon']))
+
+
+class NoAnonymousUserBackendTest(TestCase):
+    """
+    Tests that AnonymousUser does not delegate to backend if it has 'supports_anonymous_user' = False
+    """
+    backend = 'django.contrib.auth.tests.auth_backends.NoAnonymousUserBackend'
+
+    def setUp(self):
+        self.curr_auth = settings.AUTHENTICATION_BACKENDS
+        settings.AUTHENTICATION_BACKENDS = tuple(self.curr_auth) + (self.backend,)
+        self.user1 = AnonymousUser()
+
+    def tearDown(self):
+        settings.AUTHENTICATION_BACKENDS = self.curr_auth
+
+    @skipIf(True, "Do not support")
+    def test_has_perm(self):
+        self.assertEqual(self.user1.has_perm('perm', TestObj()), False)
+        self.assertEqual(self.user1.has_perm('anon', TestObj()), False)
+
+    def test_has_perms(self):
+        self.assertEqual(self.user1.has_perms(['anon'], TestObj()), False)
+
+    def test_has_module_perms(self):
+        self.assertEqual(self.user1.has_module_perms("app1"), False)
+        self.assertEqual(self.user1.has_module_perms("app2"), False)
+
+    def test_get_all_permissions(self):
+        self.assertEqual(self.user1.get_all_permissions(TestObj()), set())
diff --git a/sdncon/clusterAdmin/tests/forms.py b/sdncon/clusterAdmin/tests/forms.py
new file mode 100755
index 0000000..d70101c
--- /dev/null
+++ b/sdncon/clusterAdmin/tests/forms.py
@@ -0,0 +1,270 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.contrib.auth.models import User
+from django.contrib.auth.forms import UserCreationForm, AuthenticationForm,  PasswordChangeForm, SetPasswordForm, UserChangeForm, PasswordResetForm
+from django.test import TestCase
+from django.utils.unittest import skipIf
+
+
+class UserCreationFormTest(TestCase):
+
+    fixtures = ['authtestdata.json']
+
+    def test_user_already_exists(self):
+        data = {
+            'username': 'testclient',
+            'password1': 'test123',
+            'password2': 'test123',
+            }
+        form = UserCreationForm(data)
+        self.assertFalse(form.is_valid())
+        self.assertEqual(form["username"].errors,
+                         [u'A user with that username already exists.'])
+
+    def test_invalid_data(self):
+        data = {
+            'username': 'jsmith!',
+            'password1': 'test123',
+            'password2': 'test123',
+            }
+        form = UserCreationForm(data)
+        self.assertFalse(form.is_valid())
+        self.assertEqual(form["username"].errors,
+                         [u'This value may contain only letters, numbers and @/./+/-/_ characters.'])
+
+
+    def test_password_verification(self):
+        # The verification password is incorrect.
+        data = {
+            'username': 'jsmith',
+            'password1': 'test123',
+            'password2': 'test',
+            }
+        form = UserCreationForm(data)
+        self.assertFalse(form.is_valid())
+        self.assertEqual(form["password2"].errors,
+                         [u"The two password fields didn't match."])
+
+
+    def test_both_passwords(self):
+        # One (or both) passwords weren't given
+        data = {'username': 'jsmith'}
+        form = UserCreationForm(data)
+        self.assertFalse(form.is_valid())
+        self.assertEqual(form['password1'].errors,
+                         [u'This field is required.'])
+        self.assertEqual(form['password2'].errors,
+                         [u'This field is required.'])
+
+
+        data['password2'] = 'test123'
+        form = UserCreationForm(data)
+        self.assertFalse(form.is_valid())
+        self.assertEqual(form['password1'].errors,
+                         [u'This field is required.'])
+
+    def test_success(self):
+        # The success case.
+
+        data = {
+            'username': 'jsmith@example.com',
+            'password1': 'test123',
+            'password2': 'test123',
+            }
+        form = UserCreationForm(data)
+        self.assertTrue(form.is_valid())
+        u = form.save()
+        self.assertEqual(repr(u), '<User: jsmith@example.com>')
+
+
+class AuthenticationFormTest(TestCase):
+
+    fixtures = ['authtestdata.json']
+
+    def test_invalid_username(self):
+        # The user submits an invalid username.
+
+        data = {
+            'username': 'jsmith_does_not_exist',
+            'password': 'test123',
+            }
+        form = AuthenticationForm(None, data)
+        self.assertFalse(form.is_valid())
+        self.assertEqual(form.non_field_errors(),
+                         [u'Please enter a correct username and password. Note that both fields are case-sensitive.'])
+
+    def test_inactive_user(self):
+        # The user is inactive.
+        data = {
+            'username': 'inactive',
+            'password': 'password',
+            }
+        form = AuthenticationForm(None, data)
+        self.assertFalse(form.is_valid())
+        self.assertEqual(form.non_field_errors(),
+                         [u'This account is inactive.'])
+
+
+    def test_success(self):
+        # The success case
+        data = {
+            'username': 'testclient',
+            'password': 'password',
+            }
+        form = AuthenticationForm(None, data)
+        self.assertTrue(form.is_valid())
+        self.assertEqual(form.non_field_errors(), [])
+
+
+class SetPasswordFormTest(TestCase):
+
+    fixtures = ['authtestdata.json']
+
+    def test_password_verification(self):
+        # The two new passwords do not match.
+        user = User.objects.get(username='testclient')
+        data = {
+            'new_password1': 'abc123',
+            'new_password2': 'abc',
+            }
+        form = SetPasswordForm(user, data)
+        self.assertFalse(form.is_valid())
+        self.assertEqual(form["new_password2"].errors,
+                         [u"The two password fields didn't match."])
+
+    def test_success(self):
+        user = User.objects.get(username='testclient')
+        data = {
+            'new_password1': 'abc123',
+            'new_password2': 'abc123',
+            }
+        form = SetPasswordForm(user, data)
+        self.assertTrue(form.is_valid())
+
+
+class PasswordChangeFormTest(TestCase):
+
+    fixtures = ['authtestdata.json']
+
+    def test_incorrect_password(self):
+        user = User.objects.get(username='testclient')
+        data = {
+            'old_password': 'test',
+            'new_password1': 'abc123',
+            'new_password2': 'abc123',
+            }
+        form = PasswordChangeForm(user, data)
+        self.assertFalse(form.is_valid())
+        self.assertEqual(form["old_password"].errors,
+                         [u'Your old password was entered incorrectly. Please enter it again.'])
+
+
+    def test_password_verification(self):
+        # The two new passwords do not match.
+        user = User.objects.get(username='testclient')
+        data = {
+            'old_password': 'password',
+            'new_password1': 'abc123',
+            'new_password2': 'abc',
+            }
+        form = PasswordChangeForm(user, data)
+        self.assertFalse(form.is_valid())
+        self.assertEqual(form["new_password2"].errors,
+                         [u"The two password fields didn't match."])
+
+
+    def test_success(self):
+        # The success case.
+        user = User.objects.get(username='testclient')
+        data = {
+            'old_password': 'password',
+            'new_password1': 'abc123',
+            'new_password2': 'abc123',
+            }
+        form = PasswordChangeForm(user, data)
+        self.assertTrue(form.is_valid())
+
+    def test_field_order(self):
+        # Regression test - check the order of fields:
+        user = User.objects.get(username='testclient')
+        self.assertEqual(PasswordChangeForm(user, {}).fields.keys(),
+                         ['old_password', 'new_password1', 'new_password2'])
+
+class UserChangeFormTest(TestCase):
+
+    fixtures = ['authtestdata.json']
+
+    @skipIf(True, "Do not support")
+    def test_username_validity(self):
+        user = User.objects.get(username='testclient')
+        data = {'username': 'not valid'}
+        form = UserChangeForm(data, instance=user)
+        self.assertFalse(form.is_valid())
+        self.assertEqual(form['username'].errors,
+                         [u'This value may contain only letters, numbers and @/./+/-/_ characters.'])
+
+    def test_bug_14242(self):
+        # A regression test, introduce by adding an optimization for the
+        # UserChangeForm.
+
+        class MyUserForm(UserChangeForm):
+            def __init__(self, *args, **kwargs):
+                super(MyUserForm, self).__init__(*args, **kwargs)
+                self.fields['groups'].help_text = 'These groups give users different permissions'
+
+            class Meta(UserChangeForm.Meta):
+                fields = ('groups',)
+
+        # Just check we can create it
+        form = MyUserForm({})
+
+
+class PasswordResetFormTest(TestCase):
+
+    fixtures = ['authtestdata.json']
+
+    def test_invalid_email(self):
+        data = {'email':'not valid'}
+        form = PasswordResetForm(data)
+        self.assertFalse(form.is_valid())
+        self.assertEqual(form['email'].errors,
+                         [u'Enter a valid e-mail address.'])
+
+    def test_nonexistant_email(self):
+        # Test nonexistant email address
+        data = {'email':'foo@bar.com'}
+        form = PasswordResetForm(data)
+        self.assertFalse(form.is_valid())
+        self.assertEqual(form.errors,
+                         {'email': [u"That e-mail address doesn't have an associated user account. Are you sure you've registered?"]})
+
+    def test_cleaned_data(self):
+        # Regression test
+        user = User.objects.create_user("jsmith3", "jsmith3@example.com", "test123")
+        data = {'email':'jsmith3@example.com'}
+        form = PasswordResetForm(data)
+        self.assertTrue(form.is_valid())
+        self.assertEqual(form.cleaned_data['email'], u'jsmith3@example.com')
+
+
+    def test_bug_5605(self):
+        # bug #5605, preserve the case of the user name (before the @ in the
+        # email address) when creating a user.
+        user = User.objects.create_user('forms_test2', 'tesT@EXAMple.com', 'test')
+        self.assertEqual(user.email, 'tesT@example.com')
+        user = User.objects.create_user('forms_test3', 'tesT', 'test')
+        self.assertEqual(user.email, 'tesT')
diff --git a/sdncon/clusterAdmin/tests/urls.py b/sdncon/clusterAdmin/tests/urls.py
new file mode 100755
index 0000000..a228549
--- /dev/null
+++ b/sdncon/clusterAdmin/tests/urls.py
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.conf.urls.defaults import patterns
+from django.contrib.auth.urls import urlpatterns
+from django.contrib.auth.views import password_reset
+from django.contrib.auth.decorators import login_required
+from django.http import HttpResponse
+from django.template import Template, RequestContext
+
+def remote_user_auth_view(request):
+    "Dummy view for remote user tests"
+    t = Template("Username is {{ user }}.")
+    c = RequestContext(request, {})
+    return HttpResponse(t.render(c))
+
+# special urls for auth test cases
+urlpatterns = urlpatterns + patterns('',
+    (r'^logout/custom_query/$', 'django.contrib.auth.views.logout', dict(redirect_field_name='follow')),
+    (r'^logout/next_page/$', 'django.contrib.auth.views.logout', dict(next_page='/somewhere/')),
+    (r'^remote_user/$', remote_user_auth_view),
+    (r'^password_reset_from_email/$', 'django.contrib.auth.views.password_reset', dict(from_email='staffmember@example.com')),
+    (r'^login_required/$', login_required(password_reset)),
+    (r'^login_required_login_url/$', login_required(password_reset, login_url='/somewhere/')),
+)
+
diff --git a/sdncon/clusterAdmin/tests/views.py b/sdncon/clusterAdmin/tests/views.py
new file mode 100755
index 0000000..335941e
--- /dev/null
+++ b/sdncon/clusterAdmin/tests/views.py
@@ -0,0 +1,311 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+import os
+import re
+import urllib
+
+from django.conf import settings
+from django.contrib.auth import SESSION_KEY, REDIRECT_FIELD_NAME
+from django.contrib.auth.forms import AuthenticationForm
+from django.contrib.sites.models import Site, RequestSite
+from django.contrib.auth.models import User
+from django.test import TestCase
+from django.core import mail
+from django.core.urlresolvers import reverse
+from django.utils.unittest import skipIf
+
+class AuthViewsTestCase(TestCase):
+    """
+    Helper base class for all the follow test cases.
+    """
+    fixtures = ['authtestdata.json']
+    urls = 'django.contrib.auth.tests.urls'
+
+    def setUp(self):
+        self.old_LANGUAGES = settings.LANGUAGES
+        self.old_LANGUAGE_CODE = settings.LANGUAGE_CODE
+        settings.LANGUAGES = (('en', 'English'),)
+        settings.LANGUAGE_CODE = 'en'
+        self.old_TEMPLATE_DIRS = settings.TEMPLATE_DIRS
+        settings.TEMPLATE_DIRS = (
+            os.path.join(
+                os.path.dirname(__file__),
+                'templates'
+            )
+        ,)
+
+    def tearDown(self):
+        settings.LANGUAGES = self.old_LANGUAGES
+        settings.LANGUAGE_CODE = self.old_LANGUAGE_CODE
+        settings.TEMPLATE_DIRS = self.old_TEMPLATE_DIRS
+
+    def login(self, password='password'):
+        response = self.client.post('/login/', {
+            'username': 'testclient',
+            'password': password
+            }
+        )
+        self.assertEquals(response.status_code, 302)
+        self.assert_(response['Location'].endswith(settings.LOGIN_REDIRECT_URL))
+        self.assert_(SESSION_KEY in self.client.session)
+
+class PasswordResetTest(AuthViewsTestCase):
+
+    def test_email_not_found(self):
+        "Error is raised if the provided email address isn't currently registered"
+        response = self.client.get('/password_reset/')
+        self.assertEquals(response.status_code, 200)
+        response = self.client.post('/password_reset/', {'email': 'not_a_real_email@email.com'})
+        self.assertContains(response, "That e-mail address doesn&#39;t have an associated user account")
+        self.assertEquals(len(mail.outbox), 0)
+
+    @skipIf(True, "Do not support")
+    def test_email_found(self):
+        "Email is sent if a valid email address is provided for password reset"
+        response = self.client.post('/password_reset/', {'email': 'staffmember@example.com'})
+        self.assertEquals(response.status_code, 302)
+        self.assertEquals(len(mail.outbox), 1)
+        self.assert_("http://" in mail.outbox[0].body)
+        self.assertEquals(settings.DEFAULT_FROM_EMAIL, mail.outbox[0].from_email)
+
+    @skipIf(True, "Do not support")
+    def test_email_found_custom_from(self):
+        "Email is sent if a valid email address is provided for password reset when a custom from_email is provided."
+        response = self.client.post('/password_reset_from_email/', {'email': 'staffmember@example.com'})
+        self.assertEquals(response.status_code, 302)
+        self.assertEquals(len(mail.outbox), 1)
+        self.assertEquals("staffmember@example.com", mail.outbox[0].from_email)
+
+    def _test_confirm_start(self):
+        # Start by creating the email
+        response = self.client.post('/password_reset/', {'email': 'staffmember@example.com'})
+        self.assertEquals(response.status_code, 302)
+        self.assertEquals(len(mail.outbox), 1)
+        return self._read_signup_email(mail.outbox[0])
+
+    def _read_signup_email(self, email):
+        urlmatch = re.search(r"https?://[^/]*(/.*reset/\S*)", email.body)
+        self.assert_(urlmatch is not None, "No URL found in sent email")
+        return urlmatch.group(), urlmatch.groups()[0]
+
+    @skipIf(True, "Do not support")
+    def test_confirm_valid(self):
+        url, path = self._test_confirm_start()
+        response = self.client.get(path)
+        # redirect to a 'complete' page:
+        self.assertEquals(response.status_code, 200)
+        self.assert_("Please enter your new password" in response.content)
+
+    @skipIf(True, "Do not support")
+    def test_confirm_invalid(self):
+        url, path = self._test_confirm_start()
+        # Let's munge the token in the path, but keep the same length,
+        # in case the URLconf will reject a different length.
+        path = path[:-5] + ("0"*4) + path[-1]
+
+        response = self.client.get(path)
+        self.assertEquals(response.status_code, 200)
+        self.assert_("The password reset link was invalid" in response.content)
+
+    @skipIf(True, "Do not support")
+    def test_confirm_invalid_user(self):
+        # Ensure that we get a 200 response for a non-existant user, not a 404
+        response = self.client.get('/reset/123456-1-1/')
+        self.assertEquals(response.status_code, 200)
+        self.assert_("The password reset link was invalid" in response.content)
+
+    @skipIf(True, "Do not support")
+    def test_confirm_invalid_post(self):
+        # Same as test_confirm_invalid, but trying
+        # to do a POST instead.
+        url, path = self._test_confirm_start()
+        path = path[:-5] + ("0"*4) + path[-1]
+
+        response = self.client.post(path, {'new_password1': 'anewpassword',
+                                           'new_password2':' anewpassword'})
+        # Check the password has not been changed
+        u = User.objects.get(email='staffmember@example.com')
+        self.assert_(not u.check_password("anewpassword"))
+
+    @skipIf(True, "Do not support")
+    def test_confirm_complete(self):
+        url, path = self._test_confirm_start()
+        response = self.client.post(path, {'new_password1': 'anewpassword',
+                                           'new_password2': 'anewpassword'})
+        # It redirects us to a 'complete' page:
+        self.assertEquals(response.status_code, 302)
+        # Check the password has been changed
+        u = User.objects.get(email='staffmember@example.com')
+        self.assert_(u.check_password("anewpassword"))
+
+        # Check we can't use the link again
+        response = self.client.get(path)
+        self.assertEquals(response.status_code, 200)
+        self.assert_("The password reset link was invalid" in response.content)
+
+    @skipIf(True, "Do not support")
+    def test_confirm_different_passwords(self):
+        url, path = self._test_confirm_start()
+        response = self.client.post(path, {'new_password1': 'anewpassword',
+                                           'new_password2':' x'})
+        self.assertEquals(response.status_code, 200)
+        self.assert_("The two password fields didn&#39;t match" in response.content)
+
+class ChangePasswordTest(AuthViewsTestCase):
+
+    def fail_login(self, password='password'):
+        response = self.client.post('/login/', {
+            'username': 'testclient',
+            'password': password
+            }
+        )
+        self.assertEquals(response.status_code, 200)
+        self.assert_("Please enter a correct username and password. Note that both fields are case-sensitive." in response.content)
+
+    def logout(self):
+        response = self.client.get('/logout/')
+
+    def test_password_change_fails_with_invalid_old_password(self):
+        self.login()
+        response = self.client.post('/password_change/', {
+            'old_password': 'donuts',
+            'new_password1': 'password1',
+            'new_password2': 'password1',
+            }
+        )
+        self.assertEquals(response.status_code, 200)
+        self.assert_("Your old password was entered incorrectly. Please enter it again." in response.content)
+
+    def test_password_change_fails_with_mismatched_passwords(self):
+        self.login()
+        response = self.client.post('/password_change/', {
+            'old_password': 'password',
+            'new_password1': 'password1',
+            'new_password2': 'donuts',
+            }
+        )
+        self.assertEquals(response.status_code, 200)
+        self.assert_("The two password fields didn&#39;t match." in response.content)
+
+    def test_password_change_succeeds(self):
+        self.login()
+        response = self.client.post('/password_change/', {
+            'old_password': 'password',
+            'new_password1': 'password1',
+            'new_password2': 'password1',
+            }
+        )
+        self.assertEquals(response.status_code, 302)
+        self.assert_(response['Location'].endswith('/password_change/done/'))
+        self.fail_login()
+        self.login(password='password1')
+
+class LoginTest(AuthViewsTestCase):
+
+    @skipIf(True, "Do not support")
+    def test_current_site_in_context_after_login(self):
+        response = self.client.get(reverse('django.contrib.auth.views.login'))
+        self.assertEquals(response.status_code, 200)
+        site = Site.objects.get_current()
+        self.assertEquals(response.context['site'], site)
+        self.assertEquals(response.context['site_name'], site.name)
+        self.assert_(isinstance(response.context['form'], AuthenticationForm), 
+                     'Login form is not an AuthenticationForm')
+
+    def test_security_check(self, password='password'):
+        login_url = reverse('django.contrib.auth.views.login')
+
+        # Those URLs should not pass the security check
+        for bad_url in ('http://example.com',
+                        'https://example.com',
+                        'ftp://exampel.com',
+                        '//example.com'):
+
+            nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
+                'url': login_url,
+                'next': REDIRECT_FIELD_NAME,
+                'bad_url': urllib.quote(bad_url)
+            }
+            response = self.client.post(nasty_url, {
+                'username': 'testclient',
+                'password': password,
+                }
+            )
+            self.assertEquals(response.status_code, 302)
+            self.assertFalse(bad_url in response['Location'], "%s should be blocked" % bad_url)
+
+        # Now, these URLs have an other URL as a GET parameter and therefore
+        # should be allowed
+        for url_ in ('http://example.com', 'https://example.com',
+                    'ftp://exampel.com',  '//example.com'):
+            safe_url = '%(url)s?%(next)s=/view/?param=%(safe_param)s' % {
+                'url': login_url,
+                'next': REDIRECT_FIELD_NAME,
+                'safe_param': urllib.quote(url_)
+            }
+            response = self.client.post(safe_url, {
+                    'username': 'testclient',
+                    'password': password,
+                }
+            )
+            self.assertEquals(response.status_code, 302)
+            self.assertTrue('/view/?param=%s' % url_ in response['Location'], "/view/?param=%s should be allowed" % url_)
+
+        
+class LogoutTest(AuthViewsTestCase):
+    urls = 'django.contrib.auth.tests.urls'
+
+    def confirm_logged_out(self):
+        self.assert_(SESSION_KEY not in self.client.session)
+
+    def test_logout_default(self):
+        "Logout without next_page option renders the default template"
+        self.login()
+        response = self.client.get('/logout/')
+        self.assertEquals(200, response.status_code)
+        self.assert_('Logged out' in response.content)
+        self.confirm_logged_out()
+
+    def test_14377(self):
+        # Bug 14377
+        self.login()
+        response = self.client.get('/logout/')
+        self.assertTrue('site' in response.context)
+
+    def test_logout_with_next_page_specified(self): 
+        "Logout with next_page option given redirects to specified resource"
+        self.login()
+        response = self.client.get('/logout/next_page/')
+        self.assertEqual(response.status_code, 302)
+        self.assert_(response['Location'].endswith('/somewhere/'))
+        self.confirm_logged_out()
+
+    def test_logout_with_redirect_argument(self):
+        "Logout with query string redirects to specified resource"
+        self.login()
+        response = self.client.get('/logout/?next=/login/')
+        self.assertEqual(response.status_code, 302)
+        self.assert_(response['Location'].endswith('/login/'))
+        self.confirm_logged_out()
+
+    def test_logout_with_custom_redirect_argument(self):
+        "Logout with custom query string redirects to specified resource"
+        self.login()
+        response = self.client.get('/logout/custom_query/?follow=/somewhere/')
+        self.assertEqual(response.status_code, 302)
+        self.assert_(response['Location'].endswith('/somewhere/'))
+        self.confirm_logged_out()
diff --git a/sdncon/clusterAdmin/utils.py b/sdncon/clusterAdmin/utils.py
new file mode 100755
index 0000000..0dea8d5
--- /dev/null
+++ b/sdncon/clusterAdmin/utils.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+import os
+import sdncon
+
+BSN_BASE = sdncon.SDN_ROOT
+PERSONALITY = 'vm_personality'
+
+"""
+This is a simple conditional decorator, suggested by Claudiu on Stackoverflow.com
+"""
+def conditionally(decorator, condition):
+    def moddec(f):
+        if not condition:
+            return f
+        return decorator(f)
+    return moddec
+
+def isCloudBuild():
+    pf = os.path.join(BSN_BASE, PERSONALITY)
+    return os.path.exists(pf) and "cloud" in open(pf).read()
+
+def uicontext(request):
+    expiredSession = False
+    debug = False
+    try:
+        hostname = request.META['HTTP_HOST']
+        referer = request.META['HTTP_REFERER'].split('/')
+        if referer[2] == hostname:
+            expiredSession = referer[3] not in ('account', 'logout')
+    except:
+        # Ignore any exceptions, like missing REFERER, HOST, etc.
+        pass
+    return {
+        'isCloudBuild': isCloudBuild(),
+        'expiredSession': expiredSession,
+        'debug': debug,
+    }
+
+def abc(f):
+    def blah(*args, **kwargs):
+        print 'abc'
+        return f(*args, **kwargs)
+    return blah
+
+@conditionally(abc, isCloudBuild())
+def test(): pass
+
+if __name__ == '__main__':
+    test()
+
+    
diff --git a/sdncon/clusterAdmin/views.py b/sdncon/clusterAdmin/views.py
new file mode 100755
index 0000000..851a79d
--- /dev/null
+++ b/sdncon/clusterAdmin/views.py
@@ -0,0 +1,125 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+# Create your views here.
+
+from django.contrib.auth.decorators import login_required
+from django.utils import simplejson
+from django.http import HttpResponse
+from sdncon.clusterAdmin.models import CustomerUser
+from sdncon.clusterAdmin.utils import conditionally, isCloudBuild
+from sdncon.rest.views import safe_rest_view
+
+DEFAULT_TENANT = 'default'
+JSON_DATA_TYPE = 'application/json'
+
+@safe_rest_view
+def get_node_personality(request):
+    isCloud = isCloudBuild()
+    response_data = {'cloud' : isCloud, 'controller-node' : not isCloud}
+    response_data = simplejson.dumps(response_data)
+    return HttpResponse(response_data, JSON_DATA_TYPE)
+
+@conditionally(login_required, isCloudBuild())
+@safe_rest_view
+def session_clusterAdmin(request):
+    """
+    This returns the customer and clusters, which the current session is associated with.
+    """
+    customer = {}
+    customer['user'] = request.user.username
+    customer['customer'] = DEFAULT_TENANT
+    customer['cluster'] = []
+    if request.user.is_authenticated():
+        cus = CustomerUser.objects.all()
+        for cu in cus:
+            if cu.user.username == request.user.username:
+                customer['customer'] = cu.customer.customername
+                for cluster in cu.customer.cluster_set.all():
+                    customer['cluster'].append(cluster.clustername)
+
+    response_data = simplejson.dumps(customer)
+    return HttpResponse(response_data, JSON_DATA_TYPE) 
+
+
+import random
+from django.shortcuts import render_to_response, redirect
+from .models import AuthToken
+
+@conditionally(login_required, isCloudBuild())
+def token_view(request):
+    token=''
+    for t in AuthToken.objects.filter(user=request.user):
+        token=t.id
+    return render_to_response('registration/token_view.html', {'token': token})
+
+################################################################
+
+VALID_TOKEN_CHARS = ['3', '4', '6', '7', '9', 'A', 'C', 'E', 'F', 'G',
+                     'H', 'K', 'M', 'N', 'P', 'R', 'T', 'W', 'X', 'Y']
+TOKEN_LENGTH = 16
+TOKEN_GEN_ATTEMPTS = 16  # Number of times generated token can be in DB before giving up
+
+#
+# Token Specification
+#   16 characters, hyphens every 4 characters
+#   ....-....-....-....
+#   Key is actually this string, including the -s
+#   Characters used must be in the VALID_TOKEN_CHARS array above
+# This gives a token space of 20^16
+#
+
+@conditionally(login_required, isCloudBuild())
+def token_generate(request):
+    """
+    Generate, validate and add an auth token
+    """
+
+    for try_count in range(TOKEN_GEN_ATTEMPTS):
+        token_string = ""
+        for i in range(TOKEN_LENGTH):
+            if i > 0 and i % 4 == 0:
+                token_string += '-'
+            token_string += random.choice(VALID_TOKEN_CHARS)
+        print "Generated token " + token_string
+                
+        # See if the token already exists in the DB; race condition here, but should be minimal
+        try:
+            AuthToken.objects.get(id=token_string)
+            print "Token already present in DB, try " + str(try_count)
+            token_string = ""
+        except AuthToken.DoesNotExist:  # This is what we want
+            break
+
+    if not token_string:
+        # Should probably raise an exception here
+        print "Failed to generate new auth token"
+        # Return internal server error
+        return
+
+    # Map the token to a customer or cluster
+    # For now, just map one token to the user
+
+    # Delete any existing tokens
+    for t in AuthToken.objects.filter(user=request.user):
+        print 'Deleting token', t
+        t.delete()
+
+    # Add the new token to the DB
+    token = AuthToken(id=token_string, user=request.user)
+    token.save()
+
+    return redirect('sdncon.clusterAdmin.views.token_view')
diff --git a/sdncon/constants.py b/sdncon/constants.py
new file mode 100755
index 0000000..277344a
--- /dev/null
+++ b/sdncon/constants.py
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+import os
+
+""" This file defines global constants for the system, and should not 
+import any other files to prevent circular dependencies.
+"""
+
+SDN_ROOT = "/opt/sdnplatform" if not 'SDN_ROOT' in os.environ else os.environ['SDN_ROOT']
diff --git a/sdncon/controller/__init__.py b/sdncon/controller/__init__.py
new file mode 100755
index 0000000..ce48615
--- /dev/null
+++ b/sdncon/controller/__init__.py
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from sdncon.controller.notification import init_notifications
+from sdncon.controller.config import init_config
+
+init_notifications()
+init_config()
diff --git a/sdncon/controller/admin.py b/sdncon/controller/admin.py
new file mode 100755
index 0000000..86c11c9
--- /dev/null
+++ b/sdncon/controller/admin.py
@@ -0,0 +1,22 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.contrib import admin
+#from .models import Switch, StaticFlowTableEntry, HostConfig
+
+#admin.site.register(Switch)
+#admin.site.register(StaticFlowTableEntry)
+#admin.site.register(Host)
diff --git a/sdncon/controller/bsn-tacplus-envfilter b/sdncon/controller/bsn-tacplus-envfilter
new file mode 100755
index 0000000..e8671b3
--- /dev/null
+++ b/sdncon/controller/bsn-tacplus-envfilter
@@ -0,0 +1,11 @@
+#!/usr/bin/python
+
+import os, sys
+
+PAM_SUCCESS = 0  # Successful function return
+PAM_SYSTEM_ERR = 4  # System error
+PAM_AUTH_ERR = 7 # Authentication failure
+
+# test AV pairs in os.environ here
+
+sys.exit(PAM_SUCCESS)
diff --git a/sdncon/controller/config.py b/sdncon/controller/config.py
new file mode 100755
index 0000000..708fdb5
--- /dev/null
+++ b/sdncon/controller/config.py
@@ -0,0 +1,288 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from sdncon.rest.config import add_config_handler
+"""
+from sdncon.controller.models import Feature, GlobalConfig, Controller, \
+    ControllerInterface, ControllerDomainNameServer, \
+    FirewallRule, ControllerAlias, SnmpServerConfig, ImageDropUser
+from sdncon.controller.models import TacacsPlusConfig, TacacsPlusHost
+"""
+from oswrapper import exec_os_wrapper
+import os
+import re
+import sdncon
+from django.core import serializers
+
+# FIXME: Can probably get rid of default_id when the rest of the code is
+# in place for supporting multiple controller IDs. But what about
+# unit tests where we shouldn't rely on the boot-config file existing
+def get_local_controller_id(default_id='localhost'):
+    local_controller_id = default_id
+    f = None
+    try:
+        f = open("%s/run/boot-config" % sdncon.SDN_ROOT, 'r')
+        data = f.read()
+        match = re.search("^controller-id=([0-9a-zA-Z\-]*)$", data, re.MULTILINE)
+        if match:
+            local_controller_id = match.group(1)
+    except Exception, _e:
+        # If there was any error, then just leave the controller ID as the
+        # default value.
+        pass
+    finally:
+        if f:
+            f.close()
+    return local_controller_id
+
+"""
+# Add the config handlers here. Check the comments for add_config_handler in rest/config.py
+# for a description of the calling conventions for config handlers.
+
+def network_config_handler(op, old_instance, new_instance, modified_fields):
+    valid_instance = old_instance if (op == 'DELETE') else new_instance
+    if isinstance(valid_instance, Controller):
+        controller_node = valid_instance
+        controller_id = controller_node.id
+        if op == 'DELETE':
+            # no further configuration here
+            return
+    elif isinstance(valid_instance, ControllerDomainNameServer) \
+      or isinstance(valid_instance, ControllerInterface):
+        controller_id = valid_instance.controller_id
+        try:
+            controller_node = Controller.objects.get(pk=controller_id)
+        except Exception, _e:
+            # unknown controller node during delete, no need to
+            # do anything with any of these interfaces
+            return
+    else:
+        raise Exception('Unknown model change trigger network config handler')
+
+    if controller_id != get_local_controller_id():
+        return
+
+    if op == 'DELETE':
+        # don't reconfigure the interfaces during delete, since
+        # for deletes, the values of ip/netmask don't get updated
+        dns = ControllerDomainNameServer.objects.filter(
+                        controller=controller_node).order_by('timestamp')
+        exec_os_wrapper('NetworkConfig', 'set', 
+                        [serializers.serialize("json", [controller_node]),
+                         serializers.serialize("json", dns)])
+    else:
+        # op != 'DELETE'
+        #
+        # XXX what about HA?
+        # 'ifs' below isn't filtered by controller, the NetConfig
+        # target will only select interfaces assocaited with the
+        # controller-node 'localhost.
+        dns = ControllerDomainNameServer.objects.filter(
+                        controller=controller_node).order_by('-priority')
+        ifs = ControllerInterface.objects.filter(controller=controller_node)
+        exec_os_wrapper('NetworkConfig', 'set', 
+                        [serializers.serialize("json", [controller_node]),
+                         serializers.serialize("json", dns),
+                         serializers.serialize("json", ifs)])
+
+def firewall_entry_handler(op, old_instance, new_instance, modified_fields=None):
+    #allow in on eth0 proto tcp from any to any port 80
+    print "XXX: firewall handler called-1" 
+    command = ""
+    if op == "DELETE" and str(old_instance.interface.controller) == get_local_controller_id():
+        command += "delete "
+        instance = old_instance
+    elif (op == "INSERT" or op == "UPDATE") and str(new_instance.interface.controller) == get_local_controller_id():
+        instance = new_instance
+    else:
+        return
+
+    print instance.action
+    print instance.proto
+    print instance.port
+    print instance.src_ip
+    print instance.vrrp_ip
+    print "XXX: firewall handler called-2" 
+    controller_interface = instance.interface
+    eth = 'eth' + str(controller_interface.number) #LOOK! Hardcoded to eth interface
+    proto_str = ""
+    if instance.proto != '' and instance.proto != 'vrrp':
+        proto_str = " proto " + instance.proto
+    action_str = instance.action
+    src_str = " from any"
+    if instance.src_ip != '':
+        src_str = " from " + instance.src_ip
+    dst_str = " to any"
+    if instance.vrrp_ip != '':
+        dst_str = " to " + instance.vrrp_ip 
+    print "dst_str = ", dst_str
+    port_str = ""
+    if instance.port != 0:
+        port_str = " port " + str(instance.port)
+
+    command += (action_str + " in on " + eth + proto_str + src_str + dst_str + port_str)
+    print command
+
+    exec_os_wrapper('ExecuteUfwCommand', 'set', [command])
+    if instance.port == 6633 and action_str == 'reject' and op != 'DELETE':
+        exec_os_wrapper('RestartSDNPlatform', 'set', [])
+
+def ntp_config_handler(op, old_instance, new_instance, modified_fields=None):
+    if new_instance != None:
+        exec_os_wrapper("SetNtpServer", 'set', [new_instance.ntp_server])
+
+def tz_config_handler(op, old_instance, new_instance, modified_fields=None):
+    if op == "DELETE":
+        if str(old_instance.id) != get_local_controller_id():
+            return
+        exec_os_wrapper("UnsetTimezone", 'set')
+    elif op == "INSERT" or op == "UPDATE":
+        if str(new_instance.id) != get_local_controller_id():
+            return
+        if new_instance.time_zone != None and str(new_instance.time_zone) != "":
+            exec_os_wrapper("SetTimezone", 'set', [new_instance.time_zone])
+
+def logging_server_config_handler(op, old_instance, new_instance, modified_fields=None): 
+    if op == "DELETE":
+        if str(old_instance.id) != get_local_controller_id():
+            return
+        exec_os_wrapper("UnsetSyslogServer", 'set',
+                        [old_instance.logging_server, old_instance.logging_level])
+    elif op == "INSERT" or op == "UPDATE":
+        if str(new_instance.id) != get_local_controller_id():
+            return
+        if new_instance.logging_server != "" and new_instance.logging_enabled:
+            exec_os_wrapper("SetSyslogServer", 'set',
+                            [new_instance.logging_server, new_instance.logging_level])
+        else:
+            exec_os_wrapper("UnsetSyslogServer", 'set',
+                            [new_instance.logging_server, new_instance.logging_level])
+
+def vrrp_virtual_router_id_config_handle(op, old_instance, new_instance, modified_fields=None):
+    if op == "INSERT" or op == "UPDATE":
+        exec_os_wrapper("SetVrrpVirtualRouterId", 'set',
+                        [new_instance.cluster_number])
+    
+def netvirt_feature_config_handler(op, old_instance, new_instance, modified_fields=None):
+    if op == "INSERT" or op == "UPDATE":
+        if new_instance.netvirt_feature:
+            exec_os_wrapper("SetDefaultConfig", 'set', [new_instance.netvirt_feature])
+        else:
+            exec_os_wrapper("SetStaticFlowOnlyConfig", 'set', [new_instance.netvirt_feature])
+
+def controller_alias_config_handler(op, old_instance, new_instance, modified_fields=None):
+    if op == 'INSERT' or op == 'UPDATE':
+        if str(new_instance.controller) == get_local_controller_id():
+            exec_os_wrapper("SetHostname", 'set', [new_instance.alias])
+
+def tacacs_plus_config_handler(op, old_instance, new_instance, modified_fields=None):
+
+    if isinstance(old_instance, TacacsPlusConfig):
+        if op == 'DELETE':
+            # deleting the config singleton (presumably during shutdown?)
+            return
+
+    if isinstance(old_instance, TacacsPlusConfig):
+        config_id = old_instance.id
+    else:
+        config_id = 'tacacs'
+    try:
+        config = TacacsPlusConfig.objects.get(pk=config_id)
+    except TacacsPlusConfig.DoesNotExist:
+        # cons up a dummy config object, not necessary to save it
+        config = TacacsPlusConfig()
+
+    # get current list of hosts (op==DELETE ignored here)
+    ##hosts = TacacsPlusHost.objects.order_by('timestamp')
+    def timestampSort(h1, h2):
+        return cmp(h1.timestamp, h2.timestamp)
+    hosts = sorted(TacacsPlusHost.objects.all(), timestampSort)
+
+    # XXX roth -- config is passed as-is, not as a single-element list
+    cj = serializers.serialize("json", [config])
+    hj = serializers.serialize("json", hosts)
+    print "Calling oswrapper with:", [cj, hj]
+    exec_os_wrapper('TacacsPlusConfig', 'set', [cj, hj])
+        
+def snmp_server_config_handler(op, old_instance, new_instance, modified_fields=None):
+    if op == 'DELETE':
+        exec_os_wrapper('UnsetSnmpServerConfig', 'set', [])
+    elif op == 'INSERT' or op == 'UPDATE':
+        # enable_changed is true if operation is INSERT, else compare with old instance
+        if (op == 'INSERT'):
+            enable_changed = (new_instance.server_enable is True) #since default is False
+            print 'operation= insert, enable_changed = ', enable_changed
+        else:
+            enable_changed = (new_instance.server_enable != old_instance.server_enable)
+        server_enable = new_instance.server_enable 
+        community  = '' if new_instance.community is None else new_instance.community 
+        location = '' if new_instance.location is None else new_instance.location 
+        contact  = '' if new_instance.contact is None else new_instance.contact
+
+        print "Calling oswrapper with:", [server_enable, community, location, contact, enable_changed]
+        exec_os_wrapper('SetSnmpServerConfig', 'set',
+                        [server_enable, community, location, contact, enable_changed])
+"""
+def test_config_handler(op, old_instance, new_instance, modified_fields=None):
+    pass
+
+def images_user_ssh_key_config_handler(op, old_instance, new_instance, modified_fields=None):
+    if op == 'INSERT' or op == 'UPDATE':
+        sshkey = "\"" + str(new_instance.images_user_ssh_key) + "\""
+        exec_os_wrapper('SetImagesUserSSHKey', 'set', [sshkey])
+
+def init_config():
+    # 
+    # Associate the config handlers with specific callout for each of the fields
+    #  Keep in mind that these are the django names, NOT the rest api names,
+    #
+    """
+    disabled_by_shell_variable = os.environ.get('SDNCON_CONFIG_HANDLERS_DISABLED', False)
+    disabled_by_file = os.path.exists("%s/sdncon_config_handlers_disabled" % sdncon.SDN_ROOT)
+    if not disabled_by_shell_variable and not disabled_by_file:
+        add_config_handler({Controller: ['ntp_server']}, ntp_config_handler)
+        add_config_handler({Controller: ['time_zone']}, tz_config_handler)
+        add_config_handler(
+            {
+                Controller: ['domain_lookups_enabled', 'domain_name', 'default_gateway'],
+                ControllerDomainNameServer: None,
+                ControllerInterface: ['ip', 'netmask', 'mode'],
+            }, network_config_handler)
+        add_config_handler({ControllerAlias: ['alias']}, controller_alias_config_handler)
+        add_config_handler({Controller: ['logging_enabled', 'logging_server', 'logging_level']}, logging_server_config_handler)
+        add_config_handler({Feature: ['netvirt_feature']}, netvirt_feature_config_handler)
+        add_config_handler({FirewallRule: None}, firewall_entry_handler)
+        add_config_handler({GlobalConfig: ['cluster_number']}, vrrp_virtual_router_id_config_handle)
+        add_config_handler({ TacacsPlusConfig: ["tacacs_plus_authn", "tacacs_plus_authz", "tacacs_plus_acct",
+                                                "local_authn", "local_authz",
+                                                "timeout", "key",],
+                             TacacsPlusHost: ['ip', 'key'],
+                             },
+                           tacacs_plus_config_handler)
+        add_config_handler({SnmpServerConfig: ['server_enable', 'community', 'location', 'contact']}, snmp_server_config_handler)
+        add_config_handler({ImageDropUser: ['images_user_ssh_key']}, images_user_ssh_key_config_handler)
+    else:
+        add_config_handler(
+            {
+                Controller: ['domain_lookups_enabled', 'domain_name', 'default_gateway'],
+                ControllerDomainNameServer: None,
+                ControllerInterface: ['ip', 'netmask', 'mode'],
+                ControllerAlias: ['alias'],
+                FirewallRule: None,
+                Feature: None,
+                GlobalConfig: ['ha-enabled', 'cluster-number'],
+            }, test_config_handler)
+    """
diff --git a/sdncon/controller/firewall.py b/sdncon/controller/firewall.py
new file mode 100755
index 0000000..ccf3d9b
--- /dev/null
+++ b/sdncon/controller/firewall.py
@@ -0,0 +1,68 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+#from sdncon.controller.models import ControllerAclEntry
+
+def map_controller_acl_entry_to_ufw_string(acl_entry, in_acl, interface=None, delete=False):
+    # TODO optimize this method by building an array and then joining it
+    command = "ufw "
+    
+    if delete:
+        command += "delete "
+        
+    if acl_entry['action'] == "permit":
+        command += "allow "
+    else:
+        command += "deny "
+    
+    if in_acl:
+        command += "in "
+    else:
+        command += "out "
+        
+    command += ("on " + interface + " ")
+    
+    if acl_entry['type'] == 'ip':
+        pass
+    elif acl_entry['type'] == 'tcp' or acl_entry['type'] == 'udp':
+        command += ("proto " + acl_entry['type'] + " from ")
+        if acl_entry['src_ip'] != None: # TODO check none
+            command += acl_entry['src_ip']
+            if acl_entry['src_ip_mask'] != None:
+                command += ("/" + acl_entry['src_ip_mask'] + " ")
+            else:
+                command += " "
+        else:
+            command += "any "
+            
+        if acl_entry['src_tp_port_op'] == 'eq':
+            command += ("port " + acl_entry['src_tp_port'] + " ")
+
+        command += "to "
+        if acl_entry['dst_ip'] != None: #TODO check none
+            command += acl_entry['dst_ip']
+            if acl_entry['dst_ip_mask'] != None:
+                command += ("/" + acl_entry['dst_ip_mask'] + " ")
+            else:
+                command += " "
+        else:
+            command += "any "
+            
+        if acl_entry['dst_tp_port_op'] == 'eq':
+            command += ("port " + acl_entry['dst_tp_port'] + " ")
+    return command
+    
+        
diff --git a/sdncon/controller/models.py b/sdncon/controller/models.py
new file mode 100755
index 0000000..88ac7ad
--- /dev/null
+++ b/sdncon/controller/models.py
@@ -0,0 +1,3294 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.db import models
+from django.contrib.auth.models import User
+
+from django.forms import ValidationError
+from django.core.validators import MaxValueValidator
+from sdncon.rest.validators import *
+
+import sys # for sys.maxint
+import time
+
+#
+# controller/models.py
+# ------------------------------------------------------------
+#
+# model description of the tables used to configure and 
+# view the controller state.
+#
+# these tables are used both by sdnplatform and the rest api.
+# the cli uses the rest api to read and write these tables,
+# while sdnplatform/sdnplatform has a more direct interface to the
+# tables.
+#
+# for the cli, the names of the fields are described in the
+# 'class Rest' section of each of the tables.
+#
+# for sdnplatform the names of fields have a relationship to their
+# type for sdnplatform.   If a field is a foreign key, then an '_id'
+# is appended to the name for the same field within sdnplatform.  This
+# means if a field is promoted or demoted to/from a foreign key,
+# changes need to be made in the sdnplatform code to use the updated
+# name.
+#
+# Make sure to include the nested Rest class or else they won't be
+# accessible using the REST API.
+
+#
+#
+# ------------------------------------------------------------
+
+def get_timestamp():
+    """
+    For us in models where the method of ordering the row values
+    is based on the order of creation.  
+    
+    The field is exposed to the rest api so that the value can
+    be queries, and so that the rest api may choose to order the
+    row values using its own strategy by setting the field directly
+    """
+    return int(time.time()*1000000)
+
+class Tunnel(models.Model):
+
+    id_max_length = 64
+    #
+    # fields ----------------------------------------
+
+    #
+    # Unique name of the Tunnel
+    #
+    tunnel_id = models.CharField(
+        primary_key  = True,
+        verbose_name = 'Tunnel Id',
+        help_text    = 'A unique Id for a Tunnel',
+        validators   = [ TenantNameValidator() ],
+        max_length   = id_max_length)
+    
+    path_seq = models.CharField(
+        verbose_name = 'Path Sequence',
+        help_text    = 'List of path identifiers: nodes or adjacencies',
+        blank        = True,
+        null         = True,
+        max_length   = 500)
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__ (self):
+        return self.tunnel_id
+    
+    def delete(self):
+        super(Tunnel, self).delete()
+    class Rest:
+        NAME = 'tunnel-config'
+        FIELD_INFO = (
+            {'name': 'tunnel_id',    'rest_name': 'tunnel-id'},
+            {'name': 'path_seq',     'rest_name': 'path-seq'},
+            )
+
+class Policy(models.Model):
+
+    id_max_length = 64
+    #
+    # fields ----------------------------------------
+
+    #
+    # Unique name of the Tunnel
+    #
+    sr_policy_id = models.CharField(
+        primary_key  = True,
+        verbose_name = 'SR Policy Id',
+        help_text    = 'A unique Id for a SR Policy',
+        validators   = [ TenantNameValidator() ],
+        max_length   = id_max_length)
+    
+    sr_policy_type = models.CharField(
+        verbose_name = 'SR Policy Type',
+        help_text    = 'Type of SR Policy',
+        validators   = [ TenantNameValidator() ],
+        max_length   = id_max_length)
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__ (self):
+        return self.sr_policy_id
+    
+    def delete(self):
+        super(Policy, self).delete()
+
+    class Rest:
+        NAME = 'policy-config'
+        FIELD_INFO = (
+            {'name': 'sr_policy_id',    'rest_name': 'policy-id'},
+            {'name': 'sr_policy_type',    'rest_name': 'policy-type'},
+            )
+
+#
+# ------------------------------------------------------------
+
+class Feature(models.Model):
+
+    #
+    # fields ----------------------------------------
+
+    id = models.CharField(
+        primary_key=True,
+        verbose_name='feature',
+        default='feature',
+        max_length=16)
+
+    netvirt_feature = models.BooleanField(
+        verbose_name='Network virtualization Feature Enabled',
+        help_text='Enable network virtualization feature by setting to true',
+        default=True
+        )
+
+    static_flow_pusher_feature = models.BooleanField(
+        verbose_name='Static Flow Pusher Feature Enabled',
+        help_text='Enable Static Flow Pusher feature by setting to true',
+        default=True
+        )
+    
+    performance_monitor_feature = models.BooleanField(
+        verbose_name='Performance Monitor',
+        help_text="Enable performance monitoring feature by setting to true",
+        default=False
+        )
+    
+    #
+    # end fields ----------------------------------------
+    
+    def __unicode__(self):
+        return "%s" % (self.id,)
+
+    def validate_unique(self, exclude = None):
+        if self.id != 'feature':
+            raise ValidationError("Only single feature record exists")
+
+    class Rest:
+        NAME = 'feature'
+        FIELD_INFO = (
+            {'name': 'netvirt_feature',                'rest_name': 'netvirt-feature'},
+            {'name': 'static_flow_pusher_feature', 'rest_name': 'static-flow-pusher-feature'},
+            {'name': 'performance_monitor_feature','rest_name': 'performance-monitor-feature'},
+            )
+
+"""
+#
+# ------------------------------------------------------------
+
+class GlobalConfig(models.Model):
+    #
+    # fields ----------------------------------------
+    
+    name = models.CharField(
+        primary_key=True,
+        verbose_name='Global Config Name',
+        help_text="Unique name for the global config; it's a singleton, "
+                  "so, by convention, the name should always be \"global\"",
+        default='global',
+        max_length=16)
+    
+    cluster_name = models.CharField(
+        verbose_name='Cluster Name',
+        help_text='Name for the cluster',
+        default='SDNCluster',
+        max_length=256)
+
+    cluster_number = models.IntegerField(
+        verbose_name='Cluster Number',
+        help_text='Small integral (1-255) identifier for the cluster',
+        default=0)
+
+    ha_enabled = models.BooleanField(
+        verbose_name='High Availability (HA) Enabled',
+        help_text='Is high availability (HA) enabled',
+        default=False)
+
+    #
+    # end fields ----------------------------------------
+
+    class Rest:
+        NAME = 'global-config'
+        FIELD_INFO = (
+            {'name': 'cluster_name',    'rest_name': 'cluster-name'},
+            {'name': 'cluster_number',  'rest_name': 'cluster-number'},
+            {'name': 'ha_enabled',      'rest_name': 'ha-enabled'},
+            )
+    
+#
+# ------------------------------------------------------------
+
+class TopologyConfig(models.Model):
+    #
+    # fields ----------------------------------------
+
+    id = models.CharField(
+        primary_key=True,
+        verbose_name='topology',
+        default='topology',
+        max_length=16)
+
+
+    autoportfast = models.BooleanField(
+        verbose_name='Auto PortFast',
+        help_text='Suppress sending LLDPs on fast ports.',
+        default=True
+        )
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return "%s" % (self.id,)
+
+    def validate_unique(self, exclude = None):
+        if self.id != 'topology':
+            raise ValidationError("Only single topology record exists")
+
+    class Rest:
+        NAME = 'topology-config'
+        FIELD_INFO = (
+        )
+
+
+#
+# ------------------------------------------------------------
+
+class ForwardingConfig(models.Model):
+    #
+    # fields ----------------------------------------
+
+    id = models.CharField(
+        primary_key=True,
+        verbose_name='forwarding',
+        default='forwarding',
+        max_length=16)
+
+    access_priority = models.IntegerField(
+        verbose_name='Access Flow Priority',
+        help_text='Priority for flows created by forwarding on access switches',
+        validators=[ RangeValidator(0,2**15-1) ],
+        default=10)
+
+    core_priority = models.IntegerField(
+        verbose_name='Core Flow Priority',
+        help_text='Priority for flows created by forwarding on core switches',
+        validators=[ RangeValidator(0,2**15-1) ],
+        default=20)
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return "%s" % (self.id,)
+
+    def validate_unique(self, exclude = None):
+        if self.id != 'forwarding':
+            raise ValidationError(
+                "Only a single forwarding configuration record is allowed"
+        )
+
+    class Rest:
+        NAME = 'forwarding-config'
+        FIELD_INFO = (
+            {'name': 'access_priority',    'rest_name': 'access-priority'},
+            {'name': 'core_priority',      'rest_name': 'core-priority'},
+        )
+"""
+#
+# ------------------------------------------------------------
+class Controller(models.Model):
+    #
+    # fields ----------------------------------------
+    #
+    # Note: This model should only contain config state for the controller VM,
+    # not any operational state.
+    #
+    # Note: The convention used to be that the controller ID was
+    # the IP address and port that the OpenFlow controller was listening
+    # on. In practice SDNPlatform listened on all interfaces and it's logic
+    # for determining its real IP address was unreliable, so it was
+    # changed/simplified to just always use "localhost" for the 
+    # IP address. So the controller ID was pretty much always
+    # "localhost:6633". The use of "controller here caused some
+    # confusion about whether "controller" meant the
+    # OpenFlow controller (i.e. SDNPlatform/SDNPlatform) vs. the controller VM.
+    # In the old controller model most/all of the settings concerned the
+    # OpenFlow controller not the VM>
+    # Most of the settings we now want to associate with the controller are
+    # controller VM settings (e.g. IP address, DNS, time zone) and not
+    # OpenFlow controller settings. So we're repurposing the Controller
+    # model to be the controller VM config state and not the OpenFlow
+    # controller discovered state (which was sort of broken to begin with).
+    # Currently (as of 10/2011), since we only support single node operation
+    # the controller ID is hard-coded to be localhost (probably should be
+    # something different, e.g. "default", because localhost implies a
+    # an interface which is really something separate), but eventually for
+    # multi-node operation we'll need to have unique ids for each controller
+    # node in the cluster. The easiest way would be to have the user enter
+    # something at first time config. Or possibly we could do something
+    # with GUIDs. Needs more thought...
+    id = models.CharField(
+        primary_key=True,
+        verbose_name='Controller ID',
+        help_text='Unique identifier string for the controller node',
+        validators=[ validate_controller_id ],
+        max_length=256)
+    
+    status = models.CharField(
+        verbose_name='Status',
+        help_text='cluster status of node',
+        max_length=256,
+        default='Provisioned',
+        )
+
+    domain_lookups_enabled = models.BooleanField(
+        verbose_name='Domain Lookups Enabled',
+        help_text='If domain lookups are enabled (default is True)',
+        default=True
+        )
+
+    domain_name = models.CharField(
+        verbose_name='Domain Name',
+        help_text='Domain name of the network',
+        max_length=256,
+        validators=[ DomainNameValidator() ],
+        default='',
+        blank=True)
+
+    default_gateway = models.CharField(
+        verbose_name='Default Gateway',
+        help_text='Default gateway',
+        max_length=256,
+        validators=[ IpValidator() ],
+        default='',
+        blank=True)
+    
+    ntp_server = models.CharField(
+        verbose_name='NTP Server',
+        help_text='NTP server',
+        max_length=256,
+        validators=[ IpOrDomainNameValidator() ],
+        default='',
+        blank=True,
+        null=True)
+
+    time_zone = models.CharField(
+        verbose_name='Time Zone',
+        help_text='Time zone (e.g. America/Los_Angeles)',
+        max_length=256,
+        validators=[ TimeZoneValidator() ],
+        default='UTC')
+
+    logging_enabled = models.BooleanField(
+        verbose_name='Logging Enabled',
+        help_text='Logging enabled',
+        default=False
+    )
+    
+    logging_server = models.CharField(
+        verbose_name='Logging Server',
+        help_text='Logging server',
+        max_length=256,
+        validators=[ IpOrDomainNameValidator() ],
+        default='',
+        blank=True,
+        null=True)
+    
+    logging_level = models.CharField(
+        verbose_name='Logging Level',
+        help_text='Logging level',
+        max_length=16,
+        validators=[ EnumerationValidator(('emerg', 'alert', 'crit', 'err',
+            'warning', 'notice', 'info', 'debug', '0', '1', '2', '3', '4',
+            '5', '6', '7'))],
+        default='notice'
+        )
+    
+    # IOS let's you specify the domain name(s) of the network in two
+    # ways. You can specify a single domain name with the "ip domain name <domain-name>"
+    # command. You can specify multiple domain names with multiple
+    # "ip domain list <domain-name>" commands. The domain names specified with
+    # "ip domain list" commands take precedence over the domain name specified with
+    # the "ip domain name" command, so the single "ip domain name" is only
+    # used if the domain name list is unspecified/empty/null. Kind of messy, but
+    # if we want to emulate IOS behavior I think we'll need to represent that in the
+    # model. But to simplify things for now we'll just support the single domain name.
+    
+    #domain_name_list = models.TextField(
+    #    verbose_name='Domain Name List',
+    #    help_text='List of domain names for the network, one per line',
+    #    null=True
+    #    )
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return "%s" % (self.id,)
+
+    class Rest:
+        NAME = 'controller-node'
+        FIELD_INFO = (
+            {'name': 'domain_lookups_enabled',  'rest_name': 'domain-lookups-enabled'},
+            {'name': 'domain_name',             'rest_name': 'domain-name'},
+            {'name': 'default_gateway',         'rest_name': 'default-gateway'},
+            {'name': 'ntp_server',              'rest_name': 'ntp-server'},
+            {'name': 'time_zone',               'rest_name': 'time-zone'},
+            {'name': 'logging_enabled',         'rest_name': 'logging-enabled'},
+            {'name': 'logging_server',          'rest_name': 'logging-server'},
+            {'name': 'logging_level',           'rest_name': 'logging-level'},
+            )
+
+"""
+#
+# ------------------------------------------------------------
+
+class ControllerAlias(models.Model):
+    
+    #
+    # fields ----------------------------------------
+
+    alias = models.CharField(
+        primary_key=True,
+        max_length=255,
+        help_text = "alias for controller",
+        verbose_name='alias',
+        validators=[SwitchAliasValidator()])
+    
+    controller = models.ForeignKey(
+        Controller,
+        verbose_name='Controller')
+
+    #
+    # end fields ----------------------------------------
+
+    class Rest:
+        NAME = 'controller-alias'
+#
+# ------------------------------------------------------------
+
+class ControllerInterface(models.Model):
+    
+    #
+    # fields ----------------------------------------
+    
+    controller = models.ForeignKey(
+        Controller,
+        verbose_name="Controller ID")
+    
+    type = models.CharField(
+        verbose_name='Interface Type',
+        help_text='Type of interface (e.g. "Ethernet")',
+        max_length=256,
+        default='Ethernet'
+        )
+    
+    number = models.IntegerField(
+        verbose_name="Interface Number",
+        help_text='Number of interface (non-negative integer)',
+        default=0)
+    
+    mode = models.CharField(
+        verbose_name='Mode',
+        help_text='Mode of configuring IP address ("dhcp" or "static")',
+        validators=[ EnumerationValidator(('dhcp', 'static'))],
+        max_length=32,
+        default='static')
+    
+    ip = models.CharField(
+        verbose_name='IP Address',
+        help_text='IP Address for interface',
+        validators=[ IpValidator() ],
+        max_length=15,
+        default='',
+        blank=True)
+    
+    netmask = models.CharField(
+        verbose_name='Netmask',
+        help_text='Netmask',
+        validators=[ IpValidator() ],
+        max_length=15,
+        default='',
+        blank=True)
+    
+    # provide a link between the underlying interface layer
+    # and this model's 'index number' to help manage discovered_ip
+    mac = models.CharField(
+        verbose_name="MAC Address",
+        help_text="MAC Address",
+        max_length=17, 
+        validators = [validate_mac_address],
+        blank=True,
+        null=True)
+
+    discovered_ip = models.CharField(
+        verbose_name='Discovered IP Address',
+        help_text='Discovered IP Address for interface',
+        validators=[ IpValidator() ],
+        max_length=15,
+        default='',
+        blank=True)
+    
+
+#    in_acl = models.ForeignKey(
+#        ControllerAcl,
+#        verbose_name = 'Controller input acl',
+#        blank=True,
+#        null=True)
+
+#    out_acl = models.ForeignKey(
+#        ControllerAcl,
+#        verbose_name = 'Controller output acl',
+#        blank=True,
+#        null=True)
+        
+    #
+    # end fields ----------------------------------------
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('controller', 'type', 'number')
+    
+    class Rest:
+        NAME = 'controller-interface'
+        FIELD_INFO = (
+             {'name': 'discovered_ip', 'rest_name': 'discovered-ip'},
+#            {'name': 'in_acl',        'rest_name': 'in-acl'},
+#            {'name': 'out_acl',       'rest_name': 'out-acl'},
+             )
+        
+
+#
+# ------------------------------------------------------------
+
+class FirewallRule(models.Model):
+
+    #
+    # fields ----------------------------------------
+    
+    interface = models.ForeignKey(
+        ControllerInterface,
+        verbose_name="Controller Interface")
+
+    action = models.CharField(
+        max_length=8,
+        validators=[ EnumerationValidator(('allow', 'deny', 'reject'))],
+        default='allow',
+        blank=True)
+
+    src_ip = models.CharField(
+        verbose_name='Source IP',
+        help_text='IP Address to allow traffic from',
+        validators=[ IpValidator() ],
+        max_length=15,
+        default='',
+        blank=True)
+    
+    vrrp_ip = models.CharField(
+        verbose_name='Local IP',
+        help_text='(Local) IP Address to allow traffic to',
+        validators=[ IpValidator() ],
+        max_length=15,
+        default='',
+        blank=True)
+    
+    port = models.IntegerField(
+        verbose_name='Port Number',
+        help_text='Port Number',
+        validators=[ RangeValidator(0,2**16-1) ],
+        default=0,
+        blank=True)
+    
+    proto = models.CharField(
+        verbose_name="ip proto",
+        help_text="ip protocol (tcp, udp or vrrp)", #TODO validator
+        validators=[ UfwProtocolValditor() ],
+        max_length=4,
+        default='',
+        blank=True)
+    
+    #
+    # end fields ----------------------------------------
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('interface', 'src_ip', 'vrrp_ip', 'port', 'proto')
+        
+    class Rest:
+        NAME = 'firewall-rule'
+        FIELD_INFO = (
+             {'name': 'src_ip', 'rest_name': 'src-ip'},
+             {'name': 'vrrp_ip', 'rest_name': 'vrrp-ip'},
+        )
+
+#
+# ------------------------------------------------------------
+
+class ControllerDomainNameServer(models.Model):
+    
+    controller = models.ForeignKey(
+        Controller,
+        verbose_name="Controller ID",
+        default=None,
+        null=True)
+    
+    ip = models.CharField(
+        verbose_name='IP Address',
+        help_text='IP Address of domain name server',
+        validators=[ IpValidator() ],
+        max_length=15,
+        default='')
+
+    timestamp = models.IntegerField(
+        verbose_name='timestamp',
+        help_text='Timestamp to determine order of domain name servers',
+        default = get_timestamp,
+        null=True,
+        blank=True,
+        )
+
+    #
+    # end fields ----------------------------------------
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('controller', 'ip')
+        
+    def validate_unique(self, exclude = None):
+        try:
+            exists = ControllerDomainNameServer.objects.get(controller = self.controller,
+                                                        ip = self.ip)
+            if exists.timestamp != self.timestamp:
+                print 'SHAZAM', self.timestamp
+                self.timestamp = exists.timestamp
+        except:
+            pass
+
+    class Rest:
+        NAME = 'controller-domain-name-server'
+        FIELD_INFO = (
+            )
+"""
+#
+# ------------------------------------------------------------
+
+class Switch(models.Model):
+    switch_id_length = 23
+    #
+    # fields ----------------------------------------
+
+    dpid = models.CharField(
+        primary_key=True,
+        verbose_name='Switch DPID',
+        help_text='Switch DPID - 64-bit hex separated by :',
+        max_length=switch_id_length, 
+        validators=[ validate_dpid ])
+
+    controller = models.ForeignKey(
+        Controller,
+        verbose_name='Controller ID',
+        blank=True,                           
+        null=True)
+    
+    socket_address = models.CharField(
+        verbose_name='Socket Address',
+        help_text='Socket address used for connection to controller',
+        max_length=64,
+        blank=True,
+        null=True)
+    
+    ip = models.CharField(
+        verbose_name='IP Address',
+        help_text='IP Address used for connection from controller',
+        validators=[ IpValidator() ],
+        max_length=15,
+        blank=True,
+        null=True)
+
+    active = models.BooleanField(
+        verbose_name='Active',
+        help_text='Switch is active (i.e. connected to a controller)',
+        default=False)
+
+    connected_since = models.DateTimeField(
+        verbose_name='Last Connect Time',
+        help_text='Time when the switch connected to the controller',
+        blank=True,
+        null=True)
+    
+    dp_desc = models.CharField(
+        verbose_name='Description',
+        max_length=256,
+        blank=True,
+        null=True)
+
+    hw_desc = models.CharField(
+        verbose_name='Hardware Description',
+        max_length=256,
+        blank=True,
+        null=True)
+
+    sw_desc = models.CharField(
+        verbose_name='Software Description',
+        max_length=256,
+        blank=True,
+        null=True)
+
+    serial_num = models.CharField(
+        verbose_name='Serial Number',
+        max_length=32,
+        blank=True,
+        null=True)
+
+    capabilities = models.IntegerField(
+        verbose_name='Capabilities',
+        help_text='Openflow switch capabilities',
+        validators=[ RangeValidator(0,2**32-1) ],
+        default=0)
+
+    tunneling_supported = models.BooleanField(
+        default=False,
+        )
+
+    buffers = models.IntegerField(
+        verbose_name='Max Packets',
+        help_text='Maximum number of packets buffered by the switch',
+        validators=[ RangeValidator(0,2**32-1) ],
+        blank=True,
+        null=True)
+
+    tables = models.IntegerField(
+        verbose_name='Max Tables',
+        help_text='Number of tables supported by the switch',
+        validators=[ RangeValidator(0,2**8-1) ],
+        blank=True,
+        null=True)
+
+    actions = models.IntegerField(
+        verbose_name='Actions',
+        help_text='Actions supported by the switch',
+        validators=[ RangeValidator(0,2**32-1) ],
+        default=0)
+    
+    #
+    # end fields ----------------------------------------
+
+    # LOOK! we should have an origin field to distinguish
+    # between user-specified switches and 'discovered' switches
+
+    def __unicode__(self):
+        return "%s" % self.dpid
+
+    class Rest:
+        NAME = 'switch'
+        FIELD_INFO = (
+            {'name': 'socket_address',    'rest_name': 'socket-address'},
+            {'name': 'ip',                'rest_name': 'ip-address'},
+            {'name': 'connected_since',   'rest_name': 'connected-since'},
+            {'name': 'dp_desc',           'rest_name': 'dp-desc'},
+            {'name': 'hw_desc',           'rest_name': 'hw-desc'},
+            {'name': 'sw_desc',           'rest_name': 'sw-desc'},
+            {'name': 'serial_num',        'rest_name': 'serial-num'},
+            {'name': 'tunneling_supported', 'rest_name': 'tunnel-supported'},
+            )
+#
+# ------------------------------------------------------------
+# SwitchConfig
+#  Any 'configured' (non-discovered) state associated with
+#  a switch.
+#
+#  tunnel_termination; when enabled, tunnels are constructed
+#   to any other tunnel_termination switch, building a mesh
+#   of open-flow enabled switches.  Typicall Used in virtualized
+#   environments, where openflow switches are not intended to
+#   exist in the path.
+#
+
+class SwitchConfig(models.Model):
+    switch_id_length = 23
+    #
+    # fields ----------------------------------------
+
+    dpid = models.CharField(
+        primary_key=True,
+        verbose_name='Switch DPID',
+        help_text='Switch DPID - 64-bit hex separated by :',
+        max_length=switch_id_length, 
+        validators=[ validate_dpid ])
+
+    core_switch = models.BooleanField(
+        default=False,
+        help_text='Identify core switches'
+        )
+
+    tunnel_termination = models.CharField(
+        verbose_name='Tunnel Termination',
+        help_text='Tunnel Termination ("enabled" "disabled" "default")',
+        validators=[ EnumerationValidator(('enabled', 'disabled', 'default'))],
+        default = 'default',
+        max_length=16)
+
+    #
+    # end fields ----------------------------------------
+
+
+    def validate_unique(self, exclude = None):
+        self.dpid = self.dpid.lower()
+
+    class Rest:
+        NAME = 'switch-config'
+        FIELD_INFO = (
+            {'name': 'tunnel_termination', 'rest_name': 'tunnel-termination'},
+            {'name': 'core_switch',       'rest_name': 'core-switch'},
+            )
+
+#
+# ------------------------------------------------------------
+
+class SwitchAlias(models.Model):
+    
+    #
+    # fields ----------------------------------------
+
+    id = models.CharField(
+        primary_key=True,
+        max_length=255,
+        help_text = "alias for switch",
+        verbose_name='alias',
+        validators=[SwitchAliasValidator()])
+    
+    switch = models.ForeignKey(
+        SwitchConfig,
+        verbose_name='Switch DPID')
+
+    #
+    # end fields ----------------------------------------
+
+    class Rest:
+        NAME = 'switch-alias'
+
+"""
+#
+# ------------------------------------------------------------
+
+class Port(models.Model):
+    #
+    # fields ----------------------------------------
+    #
+    # This table isn't intended to be updated via the rest api,
+    #  sdnplatform writes the table to describe a switch.
+    #
+    # The 'number' in the port model is the openflow port number,
+    #  which is a value used in setting up flow entries.  This is
+    #  not an interface name;  the 'interface name' is the 'name'
+    #  field below.  This table provides a mapping from the switch
+    #  dpid and port number to an 'interface name'.
+    #
+    # Since interface names can be configured on demand by the
+    #  switch, for example to name a tunnel, its not easy to
+    #  "guess" interface names without the switch reporting 
+    #  what interface names exist.  This leads to difficulty
+    #  in preconfiguring any associations with <switch, interface name>
+    #
+
+    # Unique identifier for the port
+    # combination of the switch DPID and the port number
+    id = models.CharField(
+        primary_key=True,
+        verbose_name='Port ID',
+        help_text = '#|switch|number',
+        max_length=48)
+    
+    switch = models.ForeignKey(
+        Switch,
+        verbose_name='Switch DPID')
+
+    number = models.IntegerField(
+        verbose_name='OF #',
+        help_text="Port open flow number",
+        validators=[ RangeValidator(0,2**16-1) ])
+    
+    hardware_address = models.CharField(
+        verbose_name="MAC Address",
+        help_text="Port MAC Address",
+        max_length=17, 
+        validators = [validate_mac_address],
+        blank=True,
+        null=True)
+    
+    name = models.CharField(
+        verbose_name='Name',
+        help_text="Port name",
+        max_length=32,
+        blank=True,
+        null=True)
+
+    config = models.IntegerField(
+        verbose_name='Configuration',
+        help_text='Configuration Flags',
+        validators=[ RangeValidator(0,2**32-1) ],
+        default=0)
+
+    state = models.IntegerField(
+        verbose_name="State",
+        help_text="State Flags",
+        validators=[ RangeValidator(0,2**32-1) ],
+        default=0)
+    
+    current_features = models.IntegerField(
+        verbose_name='Current',
+        help_text='Current Features',
+        validators=[ RangeValidator(0,2**32-1) ],
+        default=0)
+
+    advertised_features = models.IntegerField(
+        verbose_name='Advertised',
+        help_text='Advertised Features',
+        validators=[ RangeValidator(0,2**32-1) ],
+        default=0)
+
+    supported_features = models.IntegerField(
+        verbose_name='Supported',
+        help_text='Supported Features',
+        validators=[ RangeValidator(0,2**32-1) ],
+        default=0)
+
+    peer_features = models.IntegerField(
+        verbose_name='Peer',
+        help_text='Peer Features',
+        validators=[ RangeValidator(0,2**32-1) ],
+        default=0)
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return "%s" % (self.id,)
+
+    class Rest:
+        NAME = 'port'
+        FIELD_INFO = (
+            {'name': 'hardware_address',     'rest_name': 'hardware-address'},
+            {'name': 'current_features',     'rest_name': 'current-features'},
+            {'name': 'advertised_features',  'rest_name': 'advertised-features'},
+            {'name': 'supported_features',   'rest_name': 'supported-features'},
+            {'name': 'peer_features',        'rest_name': 'peer-features'},
+            )
+
+#
+# ------------------------------------------------------------
+
+class PortAlias(models.Model):
+    
+    #
+    # fields ----------------------------------------
+
+    id = models.CharField(
+        primary_key=True,
+        max_length=255,
+        help_text = "alias for port",
+        verbose_name='alias',
+        validators=[PortAliasValidator()])
+    
+    port = models.ForeignKey(
+        Port,
+        help_text = "foreign key for port alias",
+        verbose_name='Port ID')
+
+    #
+    # end fields ----------------------------------------
+
+    class Rest:
+        NAME = 'port-alias'
+#
+# ------------------------------------------------------------
+
+class SwitchInterfaceConfig(models.Model):
+    if_name_len = 32
+    #
+    # fields ----------------------------------------
+
+    switch = models.ForeignKey(
+        SwitchConfig,
+        verbose_name='Switch')
+
+    if_name = models.CharField(
+        verbose_name='If Name',
+        validators=[ SafeForPrimaryKeyValidator() ],
+        max_length=32)
+
+    mode = models.CharField(
+        verbose_name='Mode',
+        help_text='Interface Mode ("external", "default")',
+        validators=[ EnumerationValidator(('external','default'))],
+        max_length=32,
+        default='default')
+    
+    broadcast = models.BooleanField(
+        default=False,
+        verbose_name='Broadcast',
+        help_text='True when interfaces is an uplink to a legacy net',
+        )
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return "%s" % (self.id)
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('switch', 'if_name')
+
+    def validate_unique(self, exclude = None):
+        self.broadcast = False
+        if self.mode == 'external':
+            self.broadcast = True
+
+    class Rest:
+        NAME = 'switch-interface-config'
+        FIELD_INFO = (
+            # By using 'name' here, the 'name' from the port is identified
+            #  in the complete-from-another procedure
+            {'name': 'if_name',             'rest_name': 'name'},
+            )
+
+
+#
+# ------------------------------------------------------------
+
+class SwitchInterfaceAlias(models.Model):
+    switch_interface_alias_length = 255
+    #
+    # fields ----------------------------------------
+
+    id = models.CharField(
+        primary_key = True,
+        verbose_name = 'Switch Interface Alias',
+        help_text = 'alias',
+        max_length = switch_interface_alias_length,
+        validators=[HostAliasValidator()])
+
+    switch_interface = models.ForeignKey(
+        SwitchInterfaceConfig,
+        verbose_name='Switch Interface',
+        )
+
+    #
+    # end fields ----------------------------------------
+
+    class Rest:
+        NAME = 'switch-interface-alias'
+        FIELD_INFO = (
+            {'name': 'switch_interface', 'rest_name': 'switch-interface'},
+        )
+#
+# ------------------------------------------------------------
+
+class StaticFlowTableEntry(models.Model):
+    #
+    # fields ----------------------------------------
+
+    name = models.CharField(
+        primary_key=True,
+        verbose_name='Name', 
+        max_length=80)
+
+    switch = models.ForeignKey(
+        SwitchConfig, 
+        verbose_name="Switch DPID")
+
+    active = models.BooleanField(
+        default=False)
+    
+    # LOOK! we should hide the timeout values for static flow entry
+    # definition as they are overwritten (unless we allow these to
+    # overwrite the default that static flow pusher uses)
+    idle_timeout = models.IntegerField(
+        verbose_name="Idle Timeout", 
+        help_text="Expire flow after this many seconds of inactivity - default: 60",
+        default=60,
+        validators=[ RangeValidator(0, 2**16-1) ])
+                                       
+    hard_timeout = models.IntegerField(
+        verbose_name="Hard Timeout",
+        help_text="Seconds to expire flow, regardless of activity - default: 0",
+        default=0,
+        validators=[ RangeValidator(0, 2**16-1) ])
+
+    priority = models.IntegerField(
+        verbose_name="Priority", 
+        help_text="Priority of the flow entry",
+        default=32768,
+        validators=[ RangeValidator(0, 2**16-1) ])
+
+    cookie = models.IntegerField(
+        verbose_name="Cookie",
+        default=0) # 64-bit
+
+    #
+    # match fields
+    #
+
+    # LOOK! Need a file of python openflow constants 
+
+    # LOOK! we should hide this also or at least
+    #       for static flow entries say it is ignored
+    wildcards = models.IntegerField(
+        verbose_name="Wildcards",
+        default=0,
+        validators=[ RangeValidator(0,2**32-1) ])
+
+    in_port = models.IntegerField(
+            verbose_name="Ingress Port", 
+            blank=True, 
+            help_text="Open flow port number of ingress port",
+            null=True, 
+            validators = [ RangeValidator(0, 2**16-1) ] ) 
+
+    dl_src = models.CharField(
+            verbose_name="Src MAC", 
+            help_text="This is a 48-bit quantity specified in xx:xx:xx:xx:xx:xx format", 
+            max_length=17, 
+            blank=True, 
+            null=True,
+            validators = [ validate_mac_address ] )
+
+    dl_dst = models.CharField(
+            verbose_name="Dst MAC", 
+            help_text="Destination MAC address in the frames",
+            max_length=17, 
+            blank=True, 
+            null=True, 
+            validators = [ validate_mac_address ] )
+
+    dl_vlan = models.IntegerField(
+            verbose_name="VLAN ID",
+            help_text="VLAN ID in the frames",
+            blank=True, 
+            null=True, 
+            validators = [ RangeValidator(0, 2**12-1) ]) 
+
+    dl_vlan_pcp = models.IntegerField(
+            verbose_name="VLAN Priority", 
+            help_text="VLAN ID in the frames",
+            blank=True, 
+            null=True, 
+            validators = [ RangeValidator(0, 2**3-1) ]) 
+
+    dl_type = models.IntegerField(
+            verbose_name="Ether Type", 
+            help_text="Ether(L3) type",
+            blank=True, 
+            null=True, 
+            validators = [ RangeValidator(0, 2**16-1) ]) 
+
+    nw_tos = models.IntegerField(
+            verbose_name="TOS Bits",
+            help_text="TOS bits in the frame",
+            blank=True,
+            null=True,
+            validators = [ RangeValidator(0, 2**6-1) ]) # 6-bit DSCP value
+
+    nw_proto = models.IntegerField(
+            verbose_name="Protocol", 
+            help_text="IP (L4) protocol in the packets",
+            blank=True,
+            null=True, 
+            validators = [ RangeValidator(0, 2**8-1) ]) 
+
+    nw_src = models.CharField(
+            verbose_name="Src IP", 
+            help_text="IP v4 source address in dotted decimal a.b.c.d w/ optional mask (ex: /24)", 
+            max_length=18,
+            validators = [ CidrValidator(mask_required=False) ],
+            blank=True, 
+            null=True)
+
+    nw_dst = models.CharField(
+            verbose_name="Dst IP", 
+            help_text="IP v4 destination address in dotted decimal a.b.c.d w/ optional mask (ex: /24)", 
+            validators=[ CidrValidator(mask_required=False) ],
+            max_length=18,
+            blank=True, 
+            null=True )
+
+    tp_src = models.IntegerField(
+            verbose_name="Src Port", 
+            help_text="Source (TCP/UDP) port",
+            blank=True, 
+            null=True,
+            validators=[ RangeValidator(0, 2**16-1) ])
+
+    tp_dst = models.IntegerField(
+            verbose_name="Dst Port", 
+            help_text="Destination (TCP/UDP) port",
+            blank=True, 
+            null=True, 
+            validators=[ RangeValidator(0, 2**16-1) ])
+
+    # LOOK! have to figure out how to expose actions in the CLI - this is ugly/brittle
+    actions = models.CharField(
+            verbose_name = "Actions",
+            help_text="This is a comma-separated list of actions - a la dpctl", 
+            max_length=1024, 
+            blank=True, 
+            null=True)
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return self.name
+
+
+    class Rest:
+        NAME = 'flow-entry'
+        FIELD_INFO = (
+            {'name': 'idle_timeout',    'rest_name': 'idle-timeout'},
+            {'name': 'hard_timeout',    'rest_name': 'hard-timeout'},
+            {'name': 'in_port',         'rest_name': 'ingress-port'},
+            {'name': 'dl_src',          'rest_name': 'src-mac'},
+            {'name': 'dl_dst',          'rest_name': 'dst-mac'},
+            {'name': 'dl_vlan',         'rest_name': 'vlan-id'},
+            {'name': 'dl_vlan_pcp',     'rest_name': 'vlan-priority'},
+            {'name': 'dl_type',         'rest_name': 'ether-type'},
+            {'name': 'nw_tos',          'rest_name': 'tos-bits'},
+            {'name': 'nw_proto',        'rest_name': 'protocol'},
+            {'name': 'nw_src',          'rest_name': 'src-ip'},
+            {'name': 'nw_dst',          'rest_name': 'dst-ip'},
+            {'name': 'tp_src',          'rest_name': 'src-port'},
+            {'name': 'tp_dst',          'rest_name': 'dst-port'},
+            {'name': 'actions',         'rest_name': 'actions'},
+            )
+
+#
+# ------------------------------------------------------------
+
+class Link(models.Model):
+    #
+    # fields ----------------------------------------
+
+    id = models.CharField(
+        primary_key=True,
+        verbose_name='Link ID',
+        max_length=64)
+    
+    src_switch = models.ForeignKey(
+        Switch,
+        verbose_name='Src Switch DPID',
+        related_name='src_link_set')
+    #src_switch_id = models.CharField(
+    #    verbose_name='Src Switch ID',
+    #    max_length=32)
+    
+    name = models.CharField(
+        verbose_name='Name',
+        help_text="Link name",
+        max_length=32,
+        blank=True,
+        null=True)
+    
+    src_port = models.IntegerField(
+        verbose_name="Src Port",
+        validators=[ RangeValidator(0, 2**16-1) ])
+
+    src_port_state = models.IntegerField(
+        verbose_name="Src Port State",
+        help_text="Source Port State Flags",
+        validators=[ RangeValidator(0,2**32-1) ],
+        default=0)
+
+    dst_switch = models.ForeignKey(
+        Switch,
+        verbose_name='Dst Switch DPID',
+        related_name='dst_link_set')
+    #dst_switch_id = models.CharField(
+    #    verbose_name='Dst Switch ID',
+    #    max_length=32)
+   
+    dst_port = models.IntegerField(
+        verbose_name="Dst Port",
+        help_text="Destination Port",
+        validators=[ RangeValidator(0, 2**16-1) ])
+
+    dst_port_state = models.IntegerField(
+        verbose_name="Dst Port State",
+        help_text="Destination Port State Flags",
+        validators=[ RangeValidator(0,2**32-1) ],
+        default=0)
+
+    link_type = models.CharField(
+                            verbose_name='Link Type',
+                            help_text="Link type",
+                            max_length=10,
+                            blank=True,
+                            null=True)
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return "%s" % self.id
+
+    class Rest:
+        NAME = 'link'
+        FIELD_INFO = (
+            {'name': 'src_switch',      'rest_name': 'src-switch'},
+            {'name': 'src_port',        'rest_name': 'src-port'},
+            {'name': 'src_port_state',  'rest_name': 'src-port-state'},
+            {'name': 'dst_switch',      'rest_name': 'dst-switch'},
+            {'name': 'dst_port',        'rest_name': 'dst-port'},
+            {'name': 'dst_port_state',  'rest_name': 'dst-port-state'},
+            {'name': 'link_type',       'rest_name': 'link-type'}
+            )
+            
+"""
+"""
+#
+# ------------------------------------------------------------
+# An address-space separation
+
+class AddressSpace (models.Model):
+
+    id_max_length = 64
+
+    #
+    # fields ----------------------------------------
+
+    #
+    # Unique name of the address-space
+    #
+    name = models.CharField(
+        primary_key  = True,
+        verbose_name = 'Address Space Name',
+        help_text    = 'A unique name for an Address Space Seperation',
+        validators   = [ AddressSpaceNameValidator() ],
+        max_length   = id_max_length)
+
+    #
+    # Verbose description of this rule.
+    #
+    description = models.CharField(
+        verbose_name = 'Description',
+        help_text    = "Description of the address-space",
+        max_length   = 128,
+        blank        = True,
+        null         = True)
+   
+    #
+    # Whether the configuration is active ? By default, it is active
+    # Used to disable the configuration without having to delete the entire
+    # address-space configuration construct.
+    #
+    active = models.BooleanField(
+        verbose_name = 'Active',
+        help_text    = 'Is this Address Space active (default is True)',
+        default      = True)
+
+    #
+    # Priority of this address-space during device matching when
+    # compared to other address-spaces. Those at the same priority
+    # are used in a determinisitc alphanetical order.
+    #
+    priority = models.IntegerField(
+        verbose_name = 'Priority',
+        help_text    = 'Priority for this Address Space ' +
+                       '(higher numbers are higher priority)',
+        default      = 1000,
+        validators   = [ RangeValidator(0, 65535) ])
+
+    #
+    # Seperator tag of this address-space in the data plane, such as vlan id.
+    #
+    vlan_tag_on_egress = models.IntegerField(
+        verbose_name = 'Egress VLAN tag',
+        help_text    = 'Vlan Tag value used for this Address Space separation',
+        default      = None,
+        blank        = True,
+        null         = True,
+        validators   = [ RangeValidator(0, 4095) ])
+
+    #
+    # Origin of this configured item
+    # 
+    origin = models.CharField(
+        verbose_name = "Origin",
+        help_text    = "Values: cli, rest, other packages",
+        max_length   = 64, # in future we might use SW GUIDs for this field
+        blank        = True,
+        null         = True)
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__ (self):
+        return self.name
+
+    class Rest:
+        NAME       = 'address-space'
+        FIELD_INFO = (
+            {'name': 'vlan_tag_on_egress', 'rest_name':'vlan-tag-on-egress'},
+        )
+
+#
+# ------------------------------------------------------------
+# An identifier rule in address-space separation
+
+class AddressSpaceIdentifierRule (models.Model):
+    rule_max_length = 32 
+
+    #
+    # fields ----------------------------------------
+
+    #
+    # Create a reference to the enclosing address-space construct.
+    #
+    address_space = models.ForeignKey(
+        AddressSpace,
+        verbose_name = 'Address Space Identifier')
+
+    #
+    # Unique rule identifier name under this address-space.
+    #
+    rule = models.CharField(
+        verbose_name = 'Address Space Rule Identifier',
+        max_length   = rule_max_length)
+
+    #
+    # Verbose description of this rule.
+    #
+    description = models.CharField(
+        verbose_name = 'Description',
+        help_text    = "Description of rule",
+        max_length   = 128,
+        blank        = True,
+        null         = True)
+
+    #
+    # Whether the configuration is active ? By default, it is active
+    # Used to disable the configuration without having to delete the entire
+    # address-space identifier-rule configuration construct.
+    #
+    active = models.BooleanField(
+        verbose_name = 'Active',
+        help_text    = 'If this interface is active (default is True)',
+        default      = True)
+
+    #
+    # Priority of this address-space during device matching when
+    # compared to other address-spaces. Those at the same priority
+    # are used in a determinisitc alphanetical order.
+    #
+    priority = models.IntegerField(
+        verbose_name = 'Priority',
+        help_text    = 'Priority for this interface rule ' +
+                       '(higher numbers are higher priority)',
+        default      = 32768,
+        validators   = [ RangeValidator(0, 65535) ])
+
+    #
+    # DPID of the Switch which sent the packet
+    #
+    switch = models.CharField(
+        verbose_name = 'Switch DPID',
+        max_length   = Switch.switch_id_length,
+        help_text    = 'Switch DPID or switch alias',
+        validators   = [ validate_dpid ],
+        null         = True,
+        blank        = True)
+
+    #
+    # Range of ports in which the packet came from
+    #
+    ports = models.CharField(
+        verbose_name = "Port Range Spec",
+        help_text    = 'Port range (e.g. C12 or B1,A22-25)',
+        max_length   = 256,
+        validators   = [ PortRangeSpecValidator() ],
+        blank        = True,
+        null         = True)
+    
+    #
+    # Range of VLAN tags
+    #
+    vlans = models.CharField(
+        verbose_name = "VLAN Range Spec",
+        help_text    = "VLAN(s) (e.g. 5 or 5-10,4010-4050)",
+        max_length   = 256,
+        validators   = [ VLANRangeSpecValidator() ],
+        blank        = True,
+        null         = True)
+
+    #
+    # NameValue pair of tags
+    #
+    tag = models.CharField(
+        verbose_name = "Tag Spec",
+        help_text    = "Tag values (e.g. namespace.tagname=value)",
+        max_length   = 256,
+        validators   = [ TagSpecValidator() ],
+        blank        = True,
+        null         = True)
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__ (self):
+        return self.id
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('address_space', 'rule')
+
+    class Rest:
+        NAME = 'address-space-identifier-rule'
+        FIELD_INFO = (
+            {'name': 'description',     'rest_name': 'description'},
+            {'name': 'address_space',   'rest_name': 'address-space'},
+            {'name': 'active',          'rest_name': 'active'},
+            {'name': 'priority',        'rest_name': 'priority'},
+            {'name': 'switch',          'rest_name': 'switch'},
+            {'name': 'ports',           'rest_name': 'ports'},
+            {'name': 'vlans',           'rest_name': 'vlans'},
+            {'name': 'tag',             'rest_name': 'tag'},
+            )
+#
+# ------------------------------------------------------------
+"""
+class HostConfig(models.Model):
+    host_id_length = 17
+    #
+    # fields ----------------------------------------
+
+    #address_space = models.ForeignKey(
+    #    AddressSpace,
+    #    verbose_name = "Address space name")
+
+    mac = models.CharField(
+        verbose_name="MAC Address",
+        max_length=host_id_length, 
+        validators = [validate_mac_address])
+
+    vlan = models.CharField(
+        verbose_name='VLAN',
+        help_text='VLAN Associated with host',
+        max_length=4,
+        validators=[RangeValidator(1, 4095)],
+        blank=True,
+        default='')
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        self.mac = self.mac.lower()
+        #return "%s::%s" % (self.addressSpace, self.mac)
+        return "%s" % (self.addressSpace)
+
+    class CassandraSettings:
+        #COMPOUND_KEY_FIELDS = ('address_space', 'vlan', 'mac')
+        COMPOUND_KEY_FIELDS = ('vlan', 'mac')
+
+    def validate_unique(self, exclude = None):
+        # Invoke the default validator; error out if the vns already exists
+        super(HostConfig, self).validate_unique(exclude)
+        #if self.vlan and str(self.address_space) != 'default': 
+        #    raise ValidationError('host: vlan configured for '
+        #                          'address-space other than "default" %s' % self.address_space)
+
+    class Rest:
+        NAME = 'host-config'
+        FIELD_INFO = (
+            #{'name': 'address_space', 'rest_name': 'address-space'},
+            )
+"""
+#
+# ------------------------------------------------------------
+
+class HostSecurityIpAddress(models.Model):
+    host = models.ForeignKey(
+        HostConfig,
+        verbose_name='Host ID')
+
+    ip = models.CharField(
+        verbose_name='IP Address',
+        help_text='IP Address used to associate with host',
+        validators=[ IpValidator() ],
+        max_length=15,
+        blank=True,
+        null=True)
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return self.id
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('host', 'ip')
+
+    class Rest:
+        NAME = 'host-security-ip-address'
+        FIELD_INFO = (
+            {'name': 'ip', 'rest_name': 'ip-address'},
+            )
+
+
+#
+# ------------------------------------------------------------
+
+class HostSecurityAttachmentPoint(models.Model):
+    host = models.ForeignKey(
+        HostConfig,
+        verbose_name='Host ID')
+
+    dpid = models.CharField(
+        verbose_name = 'Switch DPID',
+        max_length   = Switch.switch_id_length,
+        help_text    = 'Switch DPID or switch alias',
+        validators   = [ validate_dpid ],
+        null         = True,
+        blank        = True)
+
+    if_name_regex = models.CharField(
+        verbose_name='If Name Regex',
+        help_text='Interface name regular expression',
+        max_length=64,
+        validators = [SafeForPrimaryKeyValidator(), IsRegexValidator()],
+        blank = True,
+        null = False,
+        )
+
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return self.id
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('host', 'dpid', 'if_name_regex')
+
+    class Rest:
+        NAME = 'host-security-attachment-point'
+        FIELD_INFO = (
+            {'name': 'if_name_regex', 'rest_name': 'if-name-regex'},
+            )
+
+#
+# ------------------------------------------------------------
+
+class HostAlias(models.Model):
+    host_alias_length = 255
+    #
+    # fields ----------------------------------------
+
+    id = models.CharField(
+        primary_key = True,
+        verbose_name = 'Host Alias',
+        help_text = 'alias',
+        max_length = host_alias_length,
+        validators=[HostAliasValidator()])
+
+    host = models.ForeignKey(
+        HostConfig,
+        verbose_name='Host ID')
+
+    #
+    # end fields ----------------------------------------
+
+    class Rest:
+        NAME = 'host-alias'
+
+class VlanConfig(models.Model):
+    #
+    # fields ----------------------------------------    
+    vlan = models.IntegerField(
+        primary_key = True,                       
+        verbose_name='VLAN',
+        help_text='VLAN Number',
+        validators=[RangeValidator(0, 4095)],
+        )
+    
+    #
+    # end fields ----------------------------------------
+    
+    def __unicode__(self):
+        if self.vlan:
+            return "%s vlan %s" % (self.vlan)
+        else:
+            return "%s vlan %s" % (self.vlan)
+    
+    class Rest:
+        NAME = 'vlan-config'
+
+#
+# ------------------------------------------------------------
+# A Static ARP table separation
+
+class StaticArp (models.Model):
+
+    id_max_length = 64
+    #
+    # fields ----------------------------------------
+    ip = models.CharField(
+        primary_key=True,
+        verbose_name='IP Address',
+        validators=[ IpValidator() ],
+        max_length=15)
+    mac = models.CharField(
+        verbose_name="MAC Address",
+        max_length=17, 
+        validators = [validate_mac_address]) 
+    #
+    # Origin of this configured item
+    # 
+    origin = models.CharField(
+        verbose_name = "Origin",
+        help_text    = "Values: cli, rest, other packages",
+        max_length   = 64, # in future we might use SW GUIDs for this field
+        blank        = True,
+        null         = True)
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__ (self):
+        return self.id
+    
+    class Rest:
+        NAME = 'static-arp'
+        
+
+
+#
+# ------------------------------------------------------------
+# A Tenant separation
+
+class Tenant (models.Model):
+
+    id_max_length = 64
+    #
+    # fields ----------------------------------------
+
+    #
+    # Unique name of the tenant
+    #
+    name = models.CharField(
+        primary_key  = True,
+        verbose_name = 'Tenant Name',
+        help_text    = 'A unique name for an Tenant',
+        validators   = [ TenantNameValidator() ],
+        max_length   = id_max_length)
+
+    #
+    # Verbose description of this tenant.
+    #
+    description = models.CharField(
+        verbose_name = 'Description',
+        help_text    = "Description of the tenant",
+        max_length   = 128,
+        blank        = True,
+        null         = True)
+   
+    #
+    # Whether the configuration is active ? By default, it is active
+    # Used to disable the configuration without having to delete the entire
+    # tenant configuration construct.
+    #
+    active = models.BooleanField(
+        verbose_name = 'Active',
+        help_text    = 'Is this Tenant active (default is True)',
+        default      = True)
+
+    #
+    # Origin of this configured item
+    # 
+    origin = models.CharField(
+        verbose_name = "Origin",
+        help_text    = "Values: cli, rest, other packages",
+        max_length   = 64, # in future we might use SW GUIDs for this field
+        blank        = True,
+        null         = True)
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__ (self):
+        return self.name
+    
+    def delete(self):
+        if self.name=='default' or self.name =='system' or self.name =='external':
+            raise ValidationError("Default/External/System Tenant can't be deleted")
+        super(Tenant, self).delete()
+    class Rest:
+        NAME = 'tenant'
+        
+
+#
+# ------------------------------------------------------------
+# A virtual router separation
+
+class VirtualRouter (models.Model):
+
+    id_max_length = 64
+    #
+    # fields ----------------------------------------
+    vrname = models.CharField(
+        verbose_name = 'Virtual Router Name',
+        help_text    = 'A unique name for a virtual router',
+        validators   = [ GeneralNameValidator() ],
+        max_length   = id_max_length
+        )
+    
+    tenant = models.ForeignKey(
+        Tenant,
+        verbose_name='Tenant Name',
+        )
+    description = models.CharField(
+        verbose_name = 'Description',
+        help_text    = "Description of the virtual router",
+        max_length   = 128,
+        blank        = True,
+        null         = True,
+        )
+   
+    #
+    # Origin of this configured item
+    # 
+    origin = models.CharField(
+        verbose_name = "Origin",
+        help_text    = "Values: cli, rest, other packages",
+        max_length   = 64, # in future we might use SW GUIDs for this field
+        blank        = True,
+        null         = True)
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__ (self):
+        return self.id
+    
+    def validate_unique(self, exclude = None):
+        # in fat tire, only one router per tenant can be defined. this can be removed later.
+        error=False
+        try:
+            exists = VirtualRouter.objects.get(tenant = self.tenant)
+            if exists.vrname !=self.vrname:
+                error=True
+        except:
+            pass
+        if error:
+            raise ValidationError(" Virtual router %s has been defined for tenant %s, only one virtual router per tenant supported" % (exists.vrname,self.tenant))
+    
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('tenant', 'vrname')
+
+    class Rest:
+        NAME = 'virtualrouter'
+
+#
+# ------------------------------------------------------------
+# A virtual network segment
+
+class VNS(models.Model):
+    id_max_length = 64
+    #
+    # fields ----------------------------------------
+    vnsname = models.CharField(
+        verbose_name='VNS ID',
+        help_text='A unique name for a Virtual Network Segment',
+        validators=[GeneralNameValidator()],
+        max_length=id_max_length)
+    tenant=models.ForeignKey(
+        Tenant,
+        verbose_name='Tenant ID',
+        default='default')
+    #
+    # Verbose description of this rule.
+    #
+    description = models.CharField(
+        verbose_name = 'Description',
+        help_text    = "Description of the VNS",
+        max_length   = 128,
+        blank        = True,
+        null         = True)
+
+    #
+    # Reference to the address-space item. By default, we 
+    # implicitly use 'default' if this is not explicitly provided.
+    #
+    vns_address_space = models.ForeignKey(
+        AddressSpace,
+        verbose_name='Address Space Association',
+        blank=True,
+        null=True)
+
+    active = models.BooleanField(
+        verbose_name='Active',
+        help_text='If this VNS is active (default is True)',
+        default=True)
+
+    priority = models.IntegerField(
+        verbose_name='Priority',
+        help_text='Priority for this VNS (higher numbers are higher priority)',
+        default = 1000,
+        validators=[RangeValidator(0, 65535)])
+ 
+    origin = models.CharField(
+        verbose_name = "The origin/creator interface for this VNS",
+        help_text="Values: cli, rest, other packages",
+        max_length=64, # in future we might use SW GUIDs for this field
+        blank=True,
+        null=True)
+
+    arp_mode = models.CharField(
+        verbose_name = "ARP Manager Config Mode",
+        help_text="Values: always-flood, flood-if-unknown, drop-if-unknown", 
+        max_length=32, 
+        validators=[VnsArpModeValidator()],
+        default='flood-if-unknown')
+
+    dhcp_mode = models.CharField(
+        verbose_name = "DHCP Manager Config Mode",
+        help_text = "Values: always-flood, flood-if-unknown, static",
+        max_length = 20,
+        validators=[VnsDhcpModeValidator()],
+        default='flood-if-unknown')
+    
+    dhcp_ip = models.CharField(
+        verbose_name='DHCP IP Address',
+        help_text='IP Address of DHCP Server',
+        validators=[ IpValidator() ],
+        max_length=15,
+        blank=True,
+        null=True)
+
+    broadcast = models.CharField(
+        verbose_name = "Broadcast (non ARP/DHCP) Config Mode",
+        help_text = "Values: always-flood, forward-to-known, drop",
+        max_length = 20,
+        validators=[VnsBroadcastModeValidator()],
+        default='forward-to-known')
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return self.id
+
+    def delete(self):
+        #default VNS can't be deleted
+        if self.id=='default|default':
+            raise ValidationError("Default VNS can't be deleted")
+        #while address space still exist, address space default vns can't be deleted
+        #for fat tire, relationship between address space and tenant are unclear yet, the following part may need revisit
+        suffix = '-default'
+        if self.vnsname.endswith(suffix):
+            print self.vnsname
+            address_space_name = self.vnsname[:-len(suffix)]
+            error=False
+            try:
+                self.vns_address_space = AddressSpace.objects.get(name = address_space_name)
+                error=True
+            except Exception, e:
+                pass
+            if error:
+                raise ValidationError('vns %s is the default VNS of address space: %s, can not be deleted ' %
+                                         (self.vnsname,address_space_name))
+        super(VNS, self).delete()
+    # manage a magic association between vns names and 
+    # address space for vns's which end in -default
+    def validate_unique(self, exclude = None):
+        # Invoke the default validator; error out if the vns already exists
+        #for fat tire, relationship between address space and tenant are unclear yet, the following part may need revisit
+        super(VNS, self).validate_unique(exclude)
+        suffix = '-default'
+        if not 'vns_address_space' in exclude:
+            if self.vns_address_space:
+                if self.vnsname.endswith(suffix):
+                    if str(self.vns_address_space) != self.vnsname[:-len(suffix)]:
+                        raise ValidationError('vns names %s ending in -default '
+                                'must have address_space names with the same prefix: %s '
+                                % (self.vnsname, self.vns_address_space))
+            elif self.vnsname.endswith(suffix):
+                address_space_name = self.vnsname[:-len(suffix)]
+                try:
+                    self.vns_address_space = AddressSpace.objects.get(name = address_space_name)
+                except Exception, e:
+                    print e
+                    if self.vns_address_space == None:
+                        raise ValidationError('vns %s has no matching address-space %s ' %
+                                             (self.vnsname, address_space_name))
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('tenant', 'vnsname')
+
+    class Rest:
+        NAME = 'vns-definition'
+        FIELD_INFO = (
+            {'name': 'vns_address_space', 'rest_name': 'address-space'},
+            {'name': 'arp_mode',          'rest_name': 'arp-mode'},
+            {'name': 'dhcp_mode',         'rest_name': 'dhcp-mode'},
+            {'name': 'dhcp_ip',           'rest_name': 'dhcp-ip'},
+            )
+    
+#
+# ------------------------------------------------------------
+# An interface rule on a VNS
+
+class VNSInterfaceRule(models.Model):
+    rule_max_length = 32 
+
+    #
+    # fields ----------------------------------------
+
+    vns = models.ForeignKey(
+        VNS,
+        verbose_name='VNS ID')
+
+    rule = models.CharField(
+        verbose_name='VNS Rule ID',
+        max_length=rule_max_length)
+
+    description = models.CharField(
+        verbose_name='Description',
+        help_text="Description of rule",
+        max_length=128,
+        blank=True,
+        null=True)
+
+    vlan_tag_on_egress = models.BooleanField(
+        verbose_name='Egress Vlan Tagging',
+        help_text='Tag with VLAN at egress point (default is False)',
+        default=False)
+
+    allow_multiple = models.BooleanField(
+        verbose_name='Allow Multiple',
+        help_text='If this interface allows hosts to be on multiple VNS (default is False)',
+        default=False)
+
+    active = models.BooleanField(
+        verbose_name='Active',
+        help_text='If this interface is active (default is True)',
+        default=True)
+
+    priority = models.IntegerField(
+        verbose_name='Priority',
+        help_text='Priority for this interface rule (higher numbers are higher priority)',
+        default = 32768,
+        validators=[RangeValidator(0, 65535)])
+
+    mac = models.CharField(
+        verbose_name="MAC Address",
+        help_text='MAC Address or host alias',
+        max_length=17, 
+        validators = [validate_mac_address],
+        blank=True,
+        null=True)
+
+    ip_subnet = models.CharField(
+        verbose_name="IP Subnet",
+        help_text='IP address or subnet (e.g. 192.168.1.1 or 192.168.1.0/24)',
+        max_length=31,
+        validators = [CidrValidator(False)],
+        blank=True,
+        null=True)
+
+    switch = models.CharField(
+        verbose_name='Switch DPID',
+        max_length= Switch.switch_id_length,
+        help_text='Switch DPID or switch alias',
+        validators=[ validate_dpid ],
+        null=True,
+        blank=True)
+
+    ports = models.CharField(
+        verbose_name="Port Range Spec",
+        help_text='Port range (e.g. C12 or B1,A22-25)',
+        max_length=256,
+        validators = [PortRangeSpecValidator()],
+        blank=True,
+        null=True)
+
+    vlans = models.CharField(
+        verbose_name="VLAN Range Spec",
+        help_text="VLAN(s) (e.g. 5 or 5-10,4010-4050)",
+        max_length=256,
+        validators = [VLANRangeSpecValidator()],
+        blank=True,
+        null=True)
+
+    tags = models.CharField(
+        verbose_name="Tag Spec",
+        help_text="Tag values (e.g. namespace.tagname=value)",
+        max_length=256,
+        validators = [TagSpecValidator()],
+        blank=True,
+        null=True)
+
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return self.id
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('vns', 'rule')
+
+    class Rest:
+        NAME = 'vns-interface-rule'
+        FIELD_INFO = (
+            {'name': 'description',        'rest_name': 'description'},
+            {'name': 'allow_multiple',     'rest_name': 'allow-multiple'},
+            {'name': 'active',             'rest_name': 'active'},
+            {'name': 'priority',           'rest_name': 'priority'},
+            {'name': 'mac',                'rest_name': 'mac'},
+            {'name': 'ip_subnet',          'rest_name': 'ip-subnet'},
+            {'name': 'switch',             'rest_name': 'switch'},
+            {'name': 'ports',              'rest_name': 'ports'},
+            {'name': 'vlans',              'rest_name': 'vlans'},
+            {'name': 'tags',               'rest_name': 'tags'},
+            {'name': 'vlan_tag_on_egress', 'rest_name': 'vlan-tag-on-egress'},            
+            )
+
+#
+# ------------------------------------------------------------
+
+class VNSInterfaceConfig(models.Model):
+    name_max_length = 32
+    #
+    # fields ----------------------------------------
+
+    vns = models.ForeignKey(
+        VNS,
+        verbose_name='VNS ID')
+
+    interface = models.CharField(
+        verbose_name='VNS Interface Name',
+        max_length=name_max_length,
+        validators = [VnsInterfaceNameValidator()])
+
+    rule = models.ForeignKey(
+        VNSInterfaceRule,
+        verbose_name='VNS Rule ID',
+        blank=True,
+        null=True)
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return self.id
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('vns', 'interface')
+
+    class Rest:
+        NAME = 'vns-interface-config'
+        FIELD_INFO = (
+            {'name': 'rule',  'rest_name': 'rule'},
+            )
+
+
+#
+# ------------------------------------------------------------
+
+class VNSAcl(models.Model):
+    name_max_length=32
+    #
+    # fields ----------------------------------------
+
+    vns = models.ForeignKey(
+        VNS,
+        verbose_name='VNS ID')
+
+    name = models.CharField(
+        help_text='Acl Name',
+        validators=[VnsAclNameValidator()],
+        max_length=name_max_length)
+
+    priority = models.IntegerField(
+        verbose_name='Priority',
+        help_text='Priority for this ACL (higher numbers are higher priority)',
+        default = 32768,
+        validators=[RangeValidator(0, 65535)])
+
+    description = models.CharField(
+        verbose_name='Description',
+        help_text="Description of the ACL",
+        max_length=128,
+        blank=True,
+        null=True)
+
+    #
+    # end fields ----------------------------------------
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('vns', 'name')
+
+    def __unicode__(self):
+        return self.id
+
+    class Rest:
+        NAME = 'vns-access-list'
+        FIELD_INFO = (
+            {'name': 'name',         'rest_name': 'name'},
+            {'name': 'priority',     'rest_name': 'priority'},
+            {'name': 'description',  'rest_name': 'description'},
+            )
+
+#
+# ------------------------------------------------------------
+
+class VNSAclEntry(models.Model):
+    #
+    # fields ----------------------------------------
+
+    rule = models.CharField(
+        help_text='Rule ID',
+        validators=[VnsRuleNameValidator()],
+        max_length=15)
+
+    vns_acl = models.ForeignKey(
+        VNSAcl,
+        verbose_name='VNS Acl name')
+
+    action = models.CharField(
+        verbose_name='permit or deny',
+        help_text="'permit' or 'deny'",
+        max_length=16,
+        validators=[ VnsAclEntryActionValidator() ])
+
+    type = models.CharField(
+        verbose_name='mac/ip/<0-255>/udp/tcp/icmp',
+        help_text="ACLtype either mac or ip or udp or tcp or icmp or ip-protocol-type",
+        max_length=16)
+
+    src_ip = models.CharField(
+        verbose_name='Source IP',
+        help_text='Source IP Address to match',
+        validators=[ IpValidator() ],
+        max_length=15,
+        blank=True,
+        null=True)
+
+    src_ip_mask = models.CharField(
+        verbose_name='Source IP Mask',
+        help_text='Mask to match source IP',
+        validators=[ IpValidator() ],
+        max_length=15,
+        blank=True,
+        null=True)
+
+    src_tp_port_op = models.CharField(
+        verbose_name='Source Port comparison op',
+        help_text='Compare with tcp/udp port eq/neq/any',
+        max_length=5,
+        blank=True,
+        null=True)
+    
+    src_tp_port = models.IntegerField(
+        verbose_name='Source UDP/TCP Port',
+        help_text='Source port value to compare',
+        validators=[RangeValidator(0, 65535)],
+        blank=True,
+        null=True)
+   
+    dst_ip = models.CharField(
+        verbose_name='Destination IP',
+        help_text='Destination IP Address to match',
+        validators=[ IpValidator() ],
+        max_length=15,
+        blank=True,
+        null=True)
+
+    dst_ip_mask = models.CharField(
+        verbose_name='Destination IP Mask',
+        help_text='Mask to match destination IP',
+        validators=[ IpValidator() ],
+        max_length=15,
+        blank=True,
+        null=True)
+
+    dst_tp_port_op = models.CharField(
+        verbose_name='Destination Port comparison op',
+        help_text='Compare with tcp/udp port eq/neq/any',
+        max_length=3,
+        blank=True,
+        null=True)
+    
+    dst_tp_port = models.IntegerField(
+        verbose_name='Destination UDP/TCP Port',
+        help_text='Destination port value to compare',
+        validators=[RangeValidator(0, 65535)],
+        blank=True,
+        null=True)
+
+    icmp_type = models.IntegerField(
+        verbose_name='ICMP Type',
+        help_text='Matching ICMP type icmp (blank matches all)',
+        validators=[RangeValidator(0, 255)],
+        blank=True,
+        null=True)
+
+    src_mac = models.CharField(
+        verbose_name="Source MAC Address",
+        help_text="Colon separated hex string (blank matches all)",
+        max_length=17, 
+        validators = [validate_mac_address],
+        blank=True,
+        null=True)
+    
+    dst_mac = models.CharField(
+        verbose_name="Destination MAC Address",
+        help_text="Colon separated hex string (blank matches all)",
+        max_length=17, 
+        validators = [validate_mac_address],
+        blank=True,
+        null=True)
+    
+    ether_type = models.IntegerField(
+        verbose_name='Ethernet Packet Type',
+        help_text='Standard ether type (blank matches all)',
+        validators=[RangeValidator(1536, 65535)],
+        blank=True,
+        null=True)
+
+    vlan = models.IntegerField(
+        verbose_name="VLAN ID",
+        help_text='Standard ether type (blank matches all)',
+        blank=True, 
+        null=True, 
+        validators = [ RangeValidator(0, 4095) ]) 
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return self.id
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('vns_acl', 'rule')
+
+    def validate_unique(self, exclude = None):
+        #
+        # there are three types of entries:
+        # - mac based rules
+        # - ip based rules
+        # - tcp/udp based rules
+        # 
+        # verify that for each rules, unexpected fields are not
+        #  populated
+
+        if self.type == 'mac':
+            if self.src_ip or self.src_ip_mask:
+                raise ValidationError("vns-access-list-entry mac rule:"
+                                      " src-ip/src-ip-mask specified"
+                                      "(ought to be null)")
+            if self.dst_ip or self.dst_ip_mask:
+                raise ValidationError("vns-access-list-entry mac rule:"
+                                      " dst-ip/dst-ip-mask specified "
+                                      "(ought to be null)")
+            if self.src_tp_port_op or self.src_tp_port:
+                raise ValidationError("vns-access-list-entry mac rule:"
+                                      " src-tp-port-op/src-to-port specified "
+                                      "(ought to be null)")
+            if self.dst_tp_port_op or self.dst_tp_port:
+                raise ValidationError("vns-access-list-entry mac rule:"
+                                      " dst-tp-port-op/dst-to-port specified "
+                                      "(ought to be null)")
+            if self.icmp_type:
+                raise ValidationError("vns-access-list-entry mac rule:"
+                                      " icmp_type specified "
+                                      "(ought to be null)")
+        elif self.type == 'ip' or re.match('[\d]+', self.type) or \
+            self.type == 'icmp':
+            if (self.src_tp_port_op != None or self.src_tp_port != None) and \
+                ((self.src_tp_port_op == None) or (self.src_tp_port == None)):
+                raise ValidationError("vns-access-list-entry ip rule:"
+                                      " src-tp-port-op/src-to-port specified "
+                                      "(both or neither)")
+            if (self.dst_tp_port_op != None or self.dst_tp_port != None) and \
+                ((self.dst_tp_port_op == None) or (self.dst_tp_port == None)):
+                raise ValidationError("vns-access-list-entry ip rule:"
+                                      " dst-tp-port-op/dst-to-port specified "
+                                      "(both or neither)")
+            if self.src_mac or self.dst_mac:
+                raise ValidationError("vns-access-list-entry ip rule:"
+                                      " src_mac/dst_mac specified "
+                                      "(ought to be null)")
+            if self.ether_type or self.vlan:
+                raise ValidationError("vns-access-list-entry ip rule:"
+                                      " ether-type/vlan specified "
+                                      "(ought to be null)")
+
+        elif self.type == 'tcp' or self.type == 'udp':
+            if self.src_mac or self.dst_mac:
+                raise ValidationError("vns-access-list-entry ip rule:"
+                                      " src_mac/dst_mac specified "
+                                      "(ought to be null)")
+            if self.ether_type or self.vlan:
+                raise ValidationError("vns-access-list-entry ip rule:"
+                                      " ether-type/vlan specified "
+                                      "(ought to be null)")
+
+
+    class Rest:
+        NAME = 'vns-access-list-entry'
+        FIELD_INFO = (
+            {'name': 'vns_acl',        'rest_name': 'vns-access-list'},
+            {'name': 'src_ip',         'rest_name': 'src-ip'},
+            {'name': 'src_ip_mask',    'rest_name': 'src-ip-mask'},
+            {'name': 'dst_ip',         'rest_name': 'dst-ip'},
+            {'name': 'dst_ip_mask',    'rest_name': 'dst-ip-mask'},
+            {'name': 'src_tp_port_op', 'rest_name': 'src-tp-port-op'},
+            {'name': 'src_tp_port',    'rest_name': 'src-tp-port'},
+            {'name': 'dst_tp_port_op', 'rest_name': 'dst-tp-port-op'},
+            {'name': 'dst_tp_port',    'rest_name': 'dst-tp-port'},
+            {'name': 'icmp_type',      'rest_name': 'icmp-type'},
+            {'name': 'src_mac',        'rest_name': 'src-mac'},
+            {'name': 'dst_mac',        'rest_name': 'dst-mac'},
+            {'name': 'ether_type',     'rest_name': 'ether-type'},
+            )
+
+#
+# ------------------------------------------------------------
+
+class VNSInterfaceAcl(models.Model):
+    in_out_length = 4
+
+    #
+    # fields ----------------------------------------
+
+    vns_acl = models.ForeignKey(
+        VNSAcl,
+        verbose_name='VNS Acl name')
+
+    vns_interface = models.ForeignKey(
+        VNSInterfaceConfig,
+        verbose_name='VNS Interface ID',
+        help_text='[vns id]|[interface long name]')
+
+    in_out = models.CharField(
+        verbose_name='in/out',
+        help_text='Match on packet input or output',
+        validators=[VnsInterfaceAclInOutValidator()],
+        max_length=in_out_length,
+        )
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return self.id
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('vns_interface', 'vns_acl', 'in_out')
+
+    def validate_unique(self, exclude = None):
+        acl_parts = str(self.vns_acl).split('|')
+        intf_parts = str(self.vns_interface).split('|')
+        # validate two vns parts
+        if acl_parts[0] != intf_parts[0]:
+            raise ValidationError("acl's vns %s doen't match interface vns %s" %
+                                  (acl_parts[0], intf_parts[0]))
+        error = False
+        try:
+            exists = VNSInterfaceAcl.objects.get(vns_interface=self.vns_interface, in_out=self.in_out)
+            if exists:
+                if exists.vns_acl != self.vns_acl:
+                    error = True
+        except:
+            pass
+        if error:
+            raise ValidationError("Interface %s already has an ACL in the %s direction, only one ACL per direction allowed" % (self.vns_interface, self.in_out))
+
+    class Rest:
+        NAME = 'vns-interface-access-list'
+        FIELD_INFO = (
+            {'name': 'vns_acl',       'rest_name': 'vns-access-list'},
+            {'name': 'vns_interface', 'rest_name': 'vns-interface'},
+            {'name': 'in_out',        'rest_name': 'in-out'},
+            )
+
+#
+# ------------------------------------------------------------
+# A virtual router interface separation
+
+class VirtualRouterInterface (models.Model):
+
+    id_max_length = 64
+    #
+    # fields ----------------------------------------
+    virtual_router = models.ForeignKey(
+        VirtualRouter,
+        verbose_name='Virtual Router ID')
+    #
+    # Unique name of the interface
+    #
+    vriname = models.CharField(
+        verbose_name = 'Interface Name',
+        help_text    = 'A unique name for a virtual router interface',
+        validators   = [ GeneralNameValidator() ],
+        max_length   = id_max_length)
+    #
+    # Origin of this configured item
+    # 
+    origin = models.CharField(
+        verbose_name = "Origin",
+        help_text    = "Values: cli, rest, other packages",
+        max_length   = 64, # in future we might use SW GUIDs for this field
+        blank        = True,
+        null         = True)
+    #
+    # Whether the configuration is active ? By default, it is active
+    # Used to disable the configuration without having to delete the entire
+    # interface configuration construct.
+    #
+    active = models.BooleanField(
+        verbose_name = 'Active',
+        help_text    = 'Is this interface active (default is True)',
+        default      = True)
+    vns_connected = models.ForeignKey(
+        VNS,
+        verbose_name='VNS connected to',
+        blank       =True,
+        null        =True)
+    router_connected = models.ForeignKey(
+        VirtualRouter,
+        related_name='router_connected',
+        verbose_name='Virtual Router connected to',
+        blank       =True,
+        null        =True)
+    
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__ (self):
+        return self.id
+    
+    def validate_unique(self, exclude = None):
+        def is_set(value):
+            if value != None and value != '':
+                return True
+
+        # for vns connection, verify that only the VNSs under the same tenant can be connected
+        error=False
+        if not 'vns_connected' in exclude:
+            if is_set(self.vns_connected):
+                tenant_vns_parts = str(self.vns_connected).split('|')
+                tenant_router_parts = str(self.virtual_router).split('|')
+                if tenant_vns_parts[0] != tenant_router_parts[0]:
+                    raise ValidationError(" VNS %s belongs to tenant %s, doesn't match virtual router tenant %s" %
+                                      (tenant_vns_parts[1],tenant_vns_parts[0], tenant_router_parts[0]))
+                    # verify there can only be one connection for one VNS
+                try:
+                    exists = VirtualRouterInterface.objects.get(virtual_router = self.virtual_router, vns_connected=self.vns_connected)
+                    if exists:
+                        if exists.vriname!=self.vriname:
+                            error=True
+                except:
+                    pass
+                if error:
+                    raise ValidationError(" VNS %s has been connected, multiple connections is not allowed" % self.vns_connected)
+        error = False    
+        # for router connection, verify that the same virtual router as myself can't be connected        
+        if not 'router_connected' in exclude:
+            if is_set(self.router_connected):
+                tenant_router_parts = str(self.router_connected).split('|')
+                tenant_myrouter_parts = str(self.virtual_router).split('|')
+                if tenant_router_parts[0] == tenant_myrouter_parts[0]:
+                    raise ValidationError(" Local loop conncetion is not allowed.")
+            # verify there can only be one connection for one virtual router
+                try:
+                    exists = VirtualRouterInterface.objects.get(virtual_router = self.virtual_router,router_connected=self.router_connected)
+                    if exists:
+                        if exists.vriname!=self.vriname:
+                            error=True
+                except:
+                    pass
+                if error:
+                    raise ValidationError(" Virtual Router %s has been connected, multiple connections is not allowed" % self.router_connected)
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('virtual_router', 'vriname')
+
+    class Rest:
+        NAME = 'virtualrouter-interface'
+        FIELD_INFO = (
+                      {'name': 'vns_connected',           'rest_name': 'vns-connected'},
+                      {'name': 'router_connected',        'rest_name': 'router-connected'},
+                      {'name': 'virtual_router',          'rest_name': 'virtual-router'},
+                      
+            )
+
+#
+# ------------------------------------------------------------
+# A virtual router interface address pool separation
+
+class VRInterfaceIpAddressPool (models.Model):
+
+    id_max_length = 64
+    #
+    # fields ----------------------------------------
+    virtual_router_interface = models.ForeignKey(
+        VirtualRouterInterface,
+        verbose_name='Virtual Router Interface ID')
+    #
+    # Origin of this configured item
+    # 
+    origin = models.CharField(
+        verbose_name = "Origin",
+        help_text    = "Values: cli, rest, other packages",
+        max_length   = 64,
+        blank        = True,
+        null         = True)
+    ip_address = models.CharField(
+        verbose_name='Source IP',
+        help_text='Interface IP Address',
+        validators=[ IpValidator() ],
+        max_length=15,
+        blank=True,
+        null=True)
+    subnet_mask = models.CharField(
+        verbose_name='Subnet IP Mask',
+        validators=[ IpMaskValidator() ],
+        max_length=15,
+        blank=True,
+        null=True)
+    
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__ (self):
+        return self.id
+    
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('virtual_router_interface', 'ip_address')
+
+    class Rest:
+        NAME = 'interface-address-pool'
+        FIELD_INFO = (
+                      {'name': 'virtual_router_interface',           'rest_name': 'virtual-router-interface'},
+                      {'name': 'ip_address',                         'rest_name': 'ip-address'},
+                      {'name': 'subnet_mask',                        'rest_name': 'subnet-mask'}, 
+            )
+
+
+#
+# ------------------------------------------------------------
+
+class VirtualRouterGWPool (models.Model):
+
+    id_max_length = 64
+    #
+    # fields ----------------------------------------
+    virtual_router = models.ForeignKey(
+        VirtualRouter,
+        verbose_name='Virtual Router ID')
+    #
+    # Unique name of the gateway pool
+    #
+    vrgwname = models.CharField(
+        verbose_name = 'Gateway Pool Name',
+        help_text    = 'A unique name for a virtual router gateway pool',
+        validators   = [ GeneralNameValidator() ],
+        max_length   = id_max_length)
+    
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__ (self):
+        return self.id
+    
+    def validate_unique(self, exclude = None):
+        def is_set(value):
+            if value != None and value != '':
+                return True
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('virtual_router', 'vrgwname')
+
+    class Rest:
+        NAME = 'virtualrouter-gwpool'
+        FIELD_INFO = (
+                      {'name': 'virtual_router',          'rest_name': 'virtual-router'},
+            )
+
+#
+# ------------------------------------------------------------
+# A virtual router gateway address pool separation
+
+class VRGatewayIpAddressPool (models.Model):
+
+    id_max_length = 64
+    #
+    # fields ----------------------------------------
+    virtual_router_gwpool = models.ForeignKey(
+        VirtualRouterGWPool,
+        verbose_name='Virtual Router Gateway Pool ID')
+    ip_address = models.CharField(
+        verbose_name='Gateway IP',
+        help_text='Gateway IP Address',
+        validators=[ IpValidator() ],
+        max_length=15,
+        blank=True,
+        null=True)
+    
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__ (self):
+        return self.id
+    
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('virtual_router_gwpool', 'ip_address')
+
+    class Rest:
+        NAME = 'gateway-address-pool'
+        FIELD_INFO = (
+                      {'name': 'virtual_router_gwpool', 'rest_name': 'virtual-router-gwpool'},
+                      {'name': 'ip_address', 'rest_name': 'ip-address'},
+            )
+
+class VirtualRoutingRule (models.Model):
+
+    id_max_length = 64
+    #
+    # fields ----------------------------------------
+    virtual_router = models.ForeignKey(
+        VirtualRouter,
+        verbose_name='Virtual Router ID')
+    #
+    # Origin of this configured item
+    # 
+    origin = models.CharField(
+        verbose_name = "Origin",
+        help_text    = "Values: cli, rest, other packages",
+        max_length   = 64,
+        blank        = True,
+        null         = True)
+    src_host = models.ForeignKey(
+        HostConfig,
+        verbose_name='source Host ID',
+        help_text='Source Host ID to match',
+        blank       =True,
+        null        =True)
+    src_tenant = models.ForeignKey(
+        Tenant,
+        verbose_name='source tenant ID',
+        help_text='Source tenant ID to match',
+        blank       =True,
+        null        =True)
+    src_vns = models.ForeignKey(
+        VNS,
+        verbose_name='source VNS ID',
+        help_text='Source VNS ID to match',
+        blank       =True,
+        null        =True)
+    src_ip = models.CharField(
+        verbose_name='Source IP',
+        help_text='Source IP Address to match',
+        validators=[ IpValidator() ],
+        max_length=15,
+        blank=True,
+        null=True)
+    src_ip_mask = models.CharField(
+        verbose_name='Source IP Mask',
+        help_text='Mask to match source IP',
+        validators=[ IpMaskValidator() ],
+        max_length=15,
+        blank=True,
+        null=True)
+    dst_host = models.ForeignKey(
+        HostConfig,
+        verbose_name='Destination Host ID',
+        help_text='Destination Host ID to match',
+        related_name='dest_host',
+        blank       =True,
+        null        =True)
+    dst_tenant = models.ForeignKey(
+        Tenant,
+        verbose_name='Destination tenant ID',
+        related_name='dest_tenant',
+        blank       =True,
+        null        =True)
+    dst_vns = models.ForeignKey(
+        VNS,
+        verbose_name='Destination VNS ID',
+        related_name='dest_vns',
+        blank       =True,
+        null        =True)
+    dst_ip = models.CharField(
+        verbose_name='Destination IP',
+        help_text='Destination IP Address to match',
+        validators=[ IpValidator() ],
+        max_length=15,
+        blank=True,
+        null=True)
+    dst_ip_mask = models.CharField(
+        verbose_name='Destination IP Mask',
+        help_text='Mask to match destination IP',
+        validators=[ IpMaskValidator() ],
+        max_length=15,
+        blank=True,
+        null=True)
+    outgoing_intf = models.ForeignKey(
+        VirtualRouterInterface,
+        verbose_name='Outgoing Interface',
+        blank       =True,
+        null        =True)
+    gateway_pool = models.ForeignKey(
+        VirtualRouterGWPool,
+        verbose_name='Gateway pool',
+        blank       =True,
+        null        =True)
+    nh_ip = models.CharField(
+        verbose_name='Next Hop IP',
+        help_text='Next Hop IP Address',
+        validators=[ IpValidator() ],
+        max_length=15,
+        blank=True,
+        null=True)
+    action = models.CharField(
+        verbose_name='permit or deny',
+        help_text="'permit' or 'deny'",
+        default='permit',
+        max_length=16,
+        validators=[ VnsAclEntryActionValidator() ])
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__ (self):
+        return self.id
+    
+    def validate_unique(self, exclude = None):
+        def is_set(value):
+            if value != None and value != '':
+                return True
+    #verify the outgoing interface can only be on the local virtual router interface
+        if not 'outgoing_intf' in exclude:
+            if is_set(self.outgoing_intf):
+                router_parts = str(self.outgoing_intf).split('|')
+                myrouter_parts = str(self.virtual_router).split('|')
+                if (router_parts[0] != myrouter_parts[0]) or (router_parts[1] != myrouter_parts[1]):
+                    raise ValidationError(" outgoing interface has to be local to virtual router: %s|%s" %
+                                  (myrouter_parts[0],myrouter_parts[1]))
+        #verify the gateway pool belongs to the local virtual router
+        if not 'gateway_pool' in exclude:
+            if is_set(self.gateway_pool):
+                router_parts = str(self.gateway_pool).split('|')
+                myrouter_parts = str(self.virtual_router).split('|')
+                if (router_parts[0] != myrouter_parts[0]) or (router_parts[1] != myrouter_parts[1]):
+                    raise ValidationError(" gateway pool has to be local to virtual router: %s|%s" %
+                                  (myrouter_parts[0],myrouter_parts[1]))
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('virtual_router', 'src_host', 'src_tenant','src_vns','src_ip','src_ip_mask', 'dst_host', 'dst_tenant','dst_vns','dst_ip','dst_ip_mask')
+
+    class Rest:
+        NAME = 'virtualrouter-routingrule'
+        FIELD_INFO = (
+                      {'name': 'virtual_router',           'rest_name': 'virtual-router'},
+                      {'name': 'src_tenant',               'rest_name': 'src-tenant'},
+                      {'name': 'dst_tenant',               'rest_name': 'dst-tenant'},
+                      {'name': 'src_vns',                  'rest_name': 'src-vns'},
+                      {'name': 'src_ip',                   'rest_name': 'src-ip'},
+                      {'name': 'src_ip_mask',              'rest_name': 'src-ip-mask'},
+                      {'name': 'dst_ip',                   'rest_name': 'dst-ip'},
+                      {'name': 'dst_ip_mask',              'rest_name': 'dst-ip-mask'},
+                      {'name': 'nh_ip',                    'rest_name': 'nh-ip'},
+                      {'name': 'outgoing_intf',            'rest_name': 'outgoing-intf'},
+                      {'name': 'dst_host',                 'rest_name': 'dst-host'},
+                      {'name': 'src_host',                 'rest_name': 'src-host'},   
+                      {'name': 'dst_vns',                  'rest_name': 'dst-vns'},
+                      {'name': 'gateway_pool',             'rest_name': 'gateway-pool'},
+            )
+#
+# ------------------------------------------------------------
+"""
+class Tag(models.Model):
+    namespace_length = 64
+    name_length = 64
+    value_length = 64
+
+    #
+    # fields ----------------------------------------
+
+    namespace = models.CharField(
+        verbose_name='Tag Namespace',
+        help_text="Namespace of the tag",
+        max_length=namespace_length)
+
+    name = models.CharField(
+        verbose_name='Tag Name',
+        help_text="Name of the tag",
+        max_length=name_length)
+
+    value = models.CharField(
+        verbose_name='Tag Value',
+        help_text="Value of the tag",
+        max_length=value_length)
+
+    persist = models.BooleanField(
+        verbose_name='persist',
+        help_text='For any cli configured tag, include in running-config',
+        default=True)
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return self.id
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('namespace', 'name', 'value')
+
+    class Rest:
+        NAME = 'tag'
+
+#
+# ------------------------------------------------------------
+
+class TagMapping(models.Model):
+    host_id_length = 17
+    switch_id_length = 23
+    if_name_len = 32
+    vlan_str_len = 4
+    #
+    # fields ----------------------------------------
+
+    tag = models.ForeignKey(
+            Tag)
+
+    mac = models.CharField(
+        verbose_name="MAC Address",
+        max_length=host_id_length, 
+        validators = [validate_mac_address],
+        default="",
+        blank=True)
+
+    vlan = models.CharField(
+        verbose_name='VLAN',
+        max_length=vlan_str_len, 
+        help_text='VLAN Number, in the range of 1-4095. 4095 means untagged',
+        validators=[VlanStringValidator()],
+        default="",
+        blank=True)
+    
+    dpid = models.CharField(
+        verbose_name='Switch DPID',
+        help_text='Switch DPID - 64-bit hex separated by :',
+        max_length=switch_id_length, 
+        validators=[ validate_dpid ],
+        default="",
+        blank=True)
+
+    ifname = models.CharField(
+        verbose_name='If Name regular expression',
+        max_length=if_name_len,
+        default="",
+        validators=[ SafeForPrimaryKeyValidator() ],
+        blank=True)
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return self.id
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('tag', 'mac', 'vlan', 'dpid', 'ifname')
+
+    def validate_unique(self, exclude = None):
+        if self.mac != '':
+            self.mac = self.mac.lower()
+
+        if self.dpid != '':
+            self.dpid = self.dpid.lower()
+
+        # don't allow all default values for the association
+        if self.mac == '' and self.vlan == '' and \
+            self.dpid == '' and self.ifname == '':
+           raise ValidationError("Match without any matching fields")
+
+    class Rest:
+        NAME = 'tag-mapping'
+"""
+#
+# ------------------------------------------------------------
+class TechSupportConf(models.Model):
+
+    #
+    # fields ----------------------------------------
+
+    cmd_type = models.CharField(
+        verbose_name='Type of command',
+        help_text='Enter cli or shell',
+        max_length=32)
+
+    cmd = models.CharField(
+        max_length=256,
+        verbose_name='Command name',
+        help_text = 'Command excuted by show tech-support')
+
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return self.id
+
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ('cmd_type', 'cmd')
+
+    class Rest:
+        NAME = 'tech-support-config'
+        FIELD_INFO = (
+            {'name': 'cmd_type',  'rest_name': 'cmd-type'},
+            )
+
+#
+# ------------------------------------------------------------
+
+class TacacsPlusConfig(models.Model):
+    #
+    # fields ----------------------------------------
+
+    id = models.CharField(
+        primary_key=True,
+        verbose_name='tacacs singleton',
+        default='tacacs',
+        max_length=16)
+
+    tacacs_plus_authn = models.BooleanField(
+        verbose_name='TACACS+ Authentication Enabled',
+        help_text='Enable TACACS+ authentication by setting to true',
+        default=False
+        )
+
+    tacacs_plus_authz = models.BooleanField(
+        verbose_name='TACACS+ Authorization Enabled',
+        help_text='Enable TACACS+ authorization by setting to true',
+        default=False
+        )
+
+    tacacs_plus_acct = models.BooleanField(
+        verbose_name='TACACS+ Accounting Enabled',
+        help_text='Enable TACACS+ accounting by setting to true',
+        default=False
+        )
+
+    local_authn = models.BooleanField(
+        verbose_name='Local Authentication Enabled',
+        help_text='Enable local authentication by setting to true',
+        default=True
+        )
+
+    local_authz = models.BooleanField(
+        verbose_name='Local Authorization Enabled',
+        help_text='Enable local authorization by setting to true',
+        default=True
+        )
+
+    timeout = models.IntegerField(
+        verbose_name="TACACS+ Server Timeout",
+        help_text='Set TACACS+ server timeout in seconds',
+        default=0,
+        validators=[ RangeValidator(0, 2**16-1) ])
+    
+    key = models.CharField(
+        verbose_name='TACACS+ Pre-shared Key',
+        help_text='pre-shared key to connect to TACACS+ server(s)',
+        max_length=256,
+        blank=True,
+        default="")    
+
+    #
+    # end fields ----------------------------------------
+
+    class Rest:
+        NAME = 'tacacs-plus-config'
+        FIELD_INFO = (
+            {'name': 'tacacs_plus_authn', 'rest_name': 'tacacs-plus-authn'},
+            {'name': 'tacacs_plus_authz', 'rest_name': 'tacacs-plus-authz'},
+            {'name': 'tacacs_plus_acct',  'rest_name': 'tacacs-plus-acct'},
+            {'name': 'local_authn',       'rest_name': 'local-authn'},
+            {'name': 'local_authz',       'rest_name': 'local-authz'},
+            )
+
+#
+# ------------------------------------------------------------
+
+class TacacsPlusHost(models.Model):
+    #
+    # fields ----------------------------------------
+
+    ip = models.CharField(
+        primary_key=True,
+        verbose_name='IP Address',
+        help_text='IP Address for TACACS+ server',
+        validators=[ IpValidator() ],
+        max_length=15)
+    
+    timestamp = models.PositiveIntegerField(
+        verbose_name='timestamp',
+        help_text='Timestamp to order the tacacs servers',
+        default = get_timestamp,
+        )
+    
+    key = models.CharField(
+        verbose_name='TACACS+ Per-host Pre-shared Key',
+        help_text='pre-shared key to connect to this TACACS+ server',
+        max_length=256,
+        blank=True,
+        default="")    
+
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return "%s" % self.ip
+
+    def validate_unique(self, exclude = None):
+        try:
+            exists = TacacsPlusHost.objects.get(ip = self.ip)
+
+            if exists.timestamp != self.timestamp:
+                self.timestamp = exists.timestamp
+        except:
+            pass
+
+    class Rest:
+        NAME = 'tacacs-plus-host'
+        FIELD_INFO = (
+            )
+
+#
+#---------------------------------------------------------
+
+class SnmpServerConfig(models.Model):
+    #
+    # fields ----------------------------------------
+
+    # we just have one row entry in the table to update, so static primary key
+    id = models.CharField(
+        primary_key=True,
+        verbose_name='snmp',
+        # default='snmp',
+        max_length=16)
+
+    #
+    # Enable state of the SNMP server/agent on the controller
+    #
+    server_enable = models.BooleanField(
+        verbose_name='SNMP Server enabled',
+        help_text='Enable SNMP server by setting to true',
+        default=False
+        )
+    #
+    # Community string for accessing the SNMP server on the controller
+    #
+    community = models.CharField(
+        verbose_name = 'Community String',
+        help_text    = "Community String to access SNMP data",
+        max_length   = 128,
+        null         = True,
+        blank        = True,
+        )
+    #
+    # Location string of the SNMP server on the controller
+    #
+    location = models.CharField(
+        verbose_name = 'System Location',
+        help_text    = "Location information for the controller appliance",
+        max_length   = 128,
+        null         = True,
+        blank        = True
+        )
+    #
+    # Contact string of the SNMP server on the controller
+    #
+    contact = models.CharField(
+        verbose_name = 'System Contact',
+        help_text    = "Contact information for the controller appliance",
+        max_length   = 128,
+        null         = True,
+        blank        = True,
+        )
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return self.id
+
+    def validate_unique(self, exclude = None):
+        if self.id != 'snmp':
+            raise ValidationError("Only single snmp record exists")
+
+    class Rest:
+        NAME = 'snmp-server-config'
+        FIELD_INFO = (
+            {'name': 'server_enable',       'rest_name': 'server-enable'},
+            )
+
+#
+# ------------------------------------------------------------
+
+class ImageDropUser(models.Model):
+    #
+    # fields ----------------------------------------
+
+    # we just have one row entry in the table to update, so static primary key
+    id = models.CharField(
+        primary_key=True,
+        verbose_name='imagedropuser',
+        default='imagedropuser',
+        max_length=16)
+
+    images_user_ssh_key = models.CharField(
+        verbose_name='Image drop user SSH public key',
+        help_text='The SSH public RSA key for the images user',
+        default='',
+        max_length=600
+        )
+    #
+    # end fields ----------------------------------------
+
+    def __unicode__(self):
+        return self.id
+ 
+    def validate_unique(self, exclude = None):
+        if self.id != 'imagedropuser':
+            raise ValidationError("Only single ImageDropUser record exists")
+
+    class Rest:
+        NAME = 'image-drop-user'
+        FIELD_INFO = (
+            {'name': 'images_user_ssh_key', 'rest_name': 'images-user-ssh-key'},
+            )
+
+# robv: Commenting out for now. Doesn't work with Cassandra backend
+#class ConsoleUser(User):
+#
+#    class Meta:
+#        proxy = True
+#
+#    class Rest:
+#        NAME = 'user'
+"""
diff --git a/sdncon/controller/notification.py b/sdncon/controller/notification.py
new file mode 100755
index 0000000..ba9c97a
--- /dev/null
+++ b/sdncon/controller/notification.py
@@ -0,0 +1,126 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.db.models.signals import post_save, post_delete
+import urllib2
+import json
+
+# FIXME: It's not thread-safe to use globals here,
+# but we currently only allow a single thread per Django process,
+# so this shouldn't cause a problem. If/when we support multiple
+# threads we could fix this by using thread local variables.
+# To support true batch notifications across multiple REST calls
+# we'd need to actually store the batched up actions in the DB,
+# since the individual REST calls would be dispatched to
+# multiple processes, so we couldn't use in-memory batching of
+# the actions like we do now. The current batch support only
+# works for single REST updates/deletes with query parameters to
+# select the records that can affect multiple records.
+notifications_inited = False
+batch_level = 0
+actions = None
+
+
+def begin_batch_notification():
+    global batch_level
+    global actions
+    
+    if batch_level == 0:
+        actions = []
+    batch_level += 1
+
+
+# FIXME: Could generalize this so it's not hard-coded for SDNPlatform, but
+# since this is supposed to be a short-term mechanism for triggering the
+# storage notifications in SDNPlatform it's not clear if it makes sense to
+# invest time in cleaning this up.
+def end_batch_notification(reset=False):
+    global batch_level
+    global actions
+    
+    if reset:
+        batch_level = 0
+    elif batch_level > 0:
+        batch_level -= 1
+    
+    if batch_level == 0:
+        if actions:
+            url = 'http://localhost:8080/wm/storage/notify/json'
+            post_data = json.dumps(actions)
+            actions = None
+            request = urllib2.Request(url, post_data, {'Content-Type':'application/json'})
+            try:
+                response = urllib2.urlopen(request)
+                # FIXME: Log error if request had an error
+                _response_text = response.read() 
+            except Exception, _e: 
+                # SDNPlatform may not be running, but we don't want that to be a fatal
+                # error, so we just ignore the exception in that case.
+                pass
+        actions = None
+
+
+def do_action(sender, instance, action):
+    # If we're not already in a batch operation, start a local one
+    # for just this one change. This is so the code that actually
+    # sends the notifications to SDNPlatform can be bottle-necked through
+    # end_batch_notification
+    local_batch = batch_level == 0
+    if local_batch:
+        begin_batch_notification()  
+    
+    last_action = actions[-1] if actions else None
+    if (last_action is None or
+        # pylint: disable=W0212
+        last_action['tableName'] != sender._meta.db_table or
+        last_action['action'] != action):
+        # pylint: disable=W0212
+        last_action = {'tableName': sender._meta.db_table, 'action': action, 'keys': []}
+        actions.append(last_action)
+    
+    keys = last_action['keys']
+    if instance.pk not in keys:
+        keys.append(instance.pk)
+        
+    if local_batch:
+        end_batch_notification()
+
+
+def do_modify_notification(sender, instance):
+    do_action(sender, instance, 'MODIFY')
+    
+def do_delete_notification(sender, instance):
+    do_action(sender, instance, 'DELETE')
+
+def notification_post_save_handler(sender, **kwargs):
+    from sdncon.rest.config import is_config_model
+    if not kwargs['raw'] and (kwargs['using'] == "default") and not is_config_model(sender):
+        do_modify_notification(sender, kwargs['instance'])
+
+
+def notification_post_delete_handler(sender, **kwargs):
+    from sdncon.rest.config import is_config_model
+    if kwargs['using'] == 'default' and not is_config_model(sender):
+        do_delete_notification(sender, kwargs['instance'])
+
+
+def init_notifications():
+    global notifications_inited
+    if not notifications_inited:
+        post_save.connect(notification_post_save_handler)
+        post_delete.connect(notification_post_delete_handler)
+        notifications_inited = True
+
diff --git a/sdncon/controller/oswrapper.py b/sdncon/controller/oswrapper.py
new file mode 100755
index 0000000..73b54f8
--- /dev/null
+++ b/sdncon/controller/oswrapper.py
@@ -0,0 +1,1515 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+import os, atexit
+import glob
+from subprocess import Popen, PIPE, check_output, CalledProcessError
+import sys, traceback, socket
+from optparse import OptionParser
+from types import StringType
+import datetime
+import json
+import re
+import time
+import urllib2
+import httplib
+import fcntl, shutil
+import sys
+import tempfile
+import stat
+
+from string import Template
+from django.forms import ValidationError
+
+# Can't import from `import sdncon` -- causes circular dependency!
+SDN_ROOT = "/opt/sdnplatform" if not 'SDN_ROOT' in os.environ else os.environ['SDN_ROOT']
+
+# Big Switch Networks Enterprise OID
+BSN_ENTERPRISE_OID = '.1.3.6.1.4.1.37538'
+BSN_ENTERPRISE_OID_CONTROLLER = BSN_ENTERPRISE_OID + '.1'
+
+
+class OsWrapper():
+    """ This base class abstracts executing os binaries without using shell in a secure, hardened way.
+        Things to keep in mind when composing command templates - because we dont use shell, args to the 
+        binaries are presented as items in the list, so no need to de-specialize special characters , for 
+        example, if you want to echo something into a file, command is "echo -e abc\ndef\n" and not 
+        "echo -e \"abc\ndef\n\"", which would then result in the quotes also to be echo'ed.
+    """
+    name = "none"
+    cmds_lst_for_set = []
+    cmds_lst_for_get = []
+    sudo_required_for_set = True
+    sudo_required_for_get = False
+    def __init__(self, name, this_cmds_list_for_set, this_cmds_list_for_get, is_sudo_reqd_for_set=True, is_sudo_required_for_get=False):
+        self.name = name
+        self.cmds_lst_for_set = this_cmds_list_for_set
+        self.cmds_lst_for_get = this_cmds_list_for_get
+        self.sudo_required_for_set = is_sudo_reqd_for_set
+        self.sudo_required_for_get = is_sudo_required_for_get
+
+        self.IP_RE = re.compile(r'^(\d{1,3}\.){3}\d{1,3}$')
+        self.DomainName_RE = re.compile(r'^([a-zA-Z0-9-]+.?)+$')
+
+    def validate_ip(self, value):
+        if not self.IP_RE.match(value) or len([x for x in value.split('.') if int(x) < 256]) != 4:
+            return False, "IP must be in dotted decimal format, 234.0.59.1"
+        return True, ""
+
+    def validate_domain(self, value):
+        if not self.DomainName_RE.match(value):
+            return False, "Invalid domain name"
+        return True, ""
+
+    def exec_cmds(self, cmds_lst, cmds_args, stdout_file_lst):
+        # traverse through the list of commands needed to set this
+        # cmd_args is a list of lists of args for each of the commands in the set list.
+        ret_out_err = {'err': [], 'out': []}
+        if len(cmds_lst) != len(cmds_args):
+           # commands to args mismatch, error out and return
+           # possibly throw an exception here as well
+           ret_out_err['err'].append("Command and args mismatch")
+           return ret_out_err
+        for indx in range(len(cmds_lst)):
+            #if self.sudo_required_for_set:
+            #   cmd_string = "sudo "
+            #else:
+            #   cmd_string = "" 
+            cmd_string = ""
+            cmd_template = Template(cmd_string + cmds_lst[indx])
+            args_map = dict({}) 
+            for args_indx in range(len(cmds_args[indx])):
+                args_map["arg%d"%(args_indx+1)] = cmds_args[indx][args_indx]
+                cmd_string += cmds_args[indx][args_indx] + " "             
+            full_cmd_string = cmd_template.substitute(args_map)
+            file_for_stdout = PIPE
+            if stdout_file_lst != None and stdout_file_lst[indx] != "":
+                file_for_stdout = open(stdout_file_lst[indx], 'a')
+            sub_proc_output = Popen(full_cmd_string.rsplit(" "), shell=False, stdin=PIPE, stdout=file_for_stdout, stderr=PIPE, close_fds=True)
+            ret_out_err['err'].append([sub_proc_output.stderr.read()])
+            if file_for_stdout == PIPE:
+                ret_out_err['out'].append([sub_proc_output.stdout.read()])
+            else:
+                file_for_stdout.close()
+            # not fit for pipe io - os.system(cmd_string) # need to check for errors in commands.
+        return ret_out_err
+    
+    def exec_cmds_new(self, cmds_lst, cmds_args, useShell=False, appendStdOut=True):
+        # traverse through the list of commands needed to set this
+        # cmd_args is a list of lists of args for each of the commands in the set list.
+        ret_out_err = {'err': [], 'out': []}
+        if len(cmds_lst) != len(cmds_args):
+           # commands to args mismatch, error out and return
+           # possibly throw an exception here as wella
+           # cmds_list is a list of dict maps - [{'bin_name': <bin>, 'args_lst': <args-list>, 'stdoutfile':<filename>},...]
+           ret_out_err['err'].append("Command and args mismatch")
+           print 'cmds_lst:', cmds_lst
+           print 'cmd_args:', cmds_args
+           return ret_out_err
+        for indx in range(len(cmds_lst)):
+            #if self.sudo_required_for_set:
+            #   cmd_string = "sudo "
+            #else:
+            #   cmd_string = "" 
+            #cmd_string = ""
+            cmd_args_lst = [cmds_lst[indx]['bin_name']]
+            
+            args_map = dict({}) 
+            for args_indx in range(len(cmds_args[indx])):
+                args_map["arg%d"%(args_indx+1)] = cmds_args[indx][args_indx]
+                #cmd_string += cmds_args[indx][args_indx] + " "  
+            if 'args_lst' in cmds_lst[indx]:  
+                for args_indx in range(len(cmds_lst[indx]['args_lst'])):
+                    arg_template = Template(cmds_lst[indx]['args_lst'][args_indx])
+                    full_arg_string = arg_template.substitute(args_map)
+                    cmd_args_lst.append(full_arg_string)
+            file_for_stdout = PIPE
+            if 'stdoutfile' in cmds_lst[indx] and cmds_lst[indx]['stdoutfile'] != "":
+                fMode = 'a'
+                if not appendStdOut:
+                    fMode = 'r+'
+                file_for_stdout = open(cmds_lst[indx]['stdoutfile'] , fMode)
+            sub_proc_output = Popen(cmd_args_lst, shell=useShell, stdin=PIPE, stdout=file_for_stdout, stderr=PIPE, close_fds=True)
+            ret_out_err['err'].append(sub_proc_output.stderr.read())
+            if file_for_stdout == PIPE:
+                ret_out_err['out'].append(sub_proc_output.stdout.read())
+            else:
+                file_for_stdout.close()
+            # not fit for pipe io - os.system(cmd_string) # need to check for errors in commands.
+        return ret_out_err
+    
+    def set(self, cmds_args, stdout_file_lst):
+        return self.exec_cmds(self.cmds_lst_for_set, cmds_args, stdout_file_lst)
+    def get(self, cmds_args, stdout_file_lst):
+        return self.exec_cmds(self.cmds_lst_for_get, cmds_args, stdout_file_lst)
+    
+    def set_new(self, cmds_args_lst = [], cmds_args = [], useShell=False, appendStdOut = False):
+        if cmds_args_lst == []:
+            cmds_args_lst = self.cmds_lst_for_set
+        return self.exec_cmds_new(cmds_args_lst, cmds_args, useShell, appendStdOut)
+    def get_new(self, cmds_args_lst = [], cmds_args = [], useShell=False, appendStdOut = False):
+        if cmds_args_lst == []:
+            cmds_args_lst = self.cmds_lst_for_get 
+        return self.exec_cmds_new(cmds_args_lst, cmds_args, useShell, appendStdOut)
+    
+
+def validate_input1(validator, value): #temporarily disabling this - TBD
+    try:
+        validator(value)
+    except ValidationError, _err:
+        return False
+    return True
+
+
+def validate_input(validator, value):
+    a = True
+    #try:
+        #a, b = validator(value)
+    #except ValidationError, err:
+    #    return False
+    return a
+
+
+def dotted_decimal_to_int(ip):
+    """
+    Converts a dotted decimal IP address string to a 32 bit integer
+    """
+    bytes = ip.split('.')
+    ip_int = 0
+    for b in bytes:
+        ip_int = (ip_int << 8) + int(b)
+    return ip_int
+
+
+def same_subnet(ip1, ip2, netmask):
+    """
+    Checks whether the two ip addresses are on the same subnet as
+    determined by the netmask argument. All of the arguments are
+    dotted decimal IP address strings.
+    """
+    if ip1 == '' or ip2 == '' or netmask == '':
+        return False
+    ip1_int = dotted_decimal_to_int(ip1)
+    ip2_int = dotted_decimal_to_int(ip2)
+    netmask_int = dotted_decimal_to_int(netmask)
+    return (ip1_int & netmask_int) == (ip2_int & netmask_int)
+
+
+class NetworkConfig(OsWrapper):
+    def __init__(self, name="network_config"):
+        OsWrapper.__init__(self, name, [], [])
+
+
+    def rewrite_etc_network_interfaces(self, controller, interfaces, ret_result):
+        """
+        Return True when the /etc/network/interfaces is rewritten. Return False otherwise.
+        The file is rewritten only when the intended new contents is different from
+        the old contents, this is an attempt to not purturb the network unless something
+        really changed.
+        """
+
+        gateway = controller['fields']['default_gateway']
+        if (gateway != ''):
+            (r, m) = self.validate_ip(gateway)
+            if not r:
+                ret_result['err'].append("Default gateway: %s" % m)
+                gateway = ''
+
+        changed = False
+        new_conf = []
+        new_conf.append("# WARNING this file is automanaged by BSN controller\n")
+        new_conf.append("# DO NOT EDIT here, use CLI with 'configure'\n")
+        new_conf.append("auto lo\niface lo inet loopback\n\n")
+        for interface in interfaces:
+            if (interface['fields']['controller'] == controller['pk']):
+                num = interface['fields']['number']
+                new_conf.append("auto eth{0}\n".format(num))
+                if (interface['fields']['mode'] == 'dhcp'):
+                    new_conf.append("iface eth{0} inet dhcp\n".format(num))
+                else:
+                    ip = interface['fields']['ip']
+                    netmask = interface['fields']['netmask']
+                    if (ip != ""):
+                        (r, m) = self.validate_ip(ip)
+                        if not r:
+                            ret_result['err'].append(
+                                "Ethernet %s IP address %s: %s" % (num, ip, m))
+                            ip = ""
+                    if (netmask != ""):
+                        (r, m) = self.validate_ip(netmask)
+                        if not r:
+                            ret_result['err'].append(
+                                "Ethernet %s netmask %s: %s" % (num, netmask, m))
+                            netmask = ""
+        
+                    new_conf.append("iface eth{0} inet static\n".format(num))
+                    if (ip != ""):
+                        new_conf.append("    address {0}\n".format(ip))
+                    if (netmask != ""):
+                        new_conf.append("    netmask {0}\n".format(netmask))
+                    if same_subnet(gateway, ip, netmask):
+                        new_conf.append("    gateway {0}\n".format(gateway))
+                new_conf.append("\n")
+
+        f = open("/etc/network/interfaces", "r")
+        if (''.join(new_conf) != f.read()):
+            f.close()
+            f = open("/etc/network/interfaces", "w")
+            f.write(''.join(new_conf))
+            changed = True
+        f.close()
+        return changed
+
+    def rewrite_etc_resolve_conf(self, controller, dns_servers, ret_result):
+        """
+        Return True when the /etc/resolv.conf is rewritten. Return False otherwise.
+        The file is rewritten only when the intended new contents is different from
+        the old contents, this is an attempt to not purturb the network unless something
+        really changed.
+        """
+
+        changed = False
+        new_conf = []
+        domain_name = controller['fields']['domain_name']
+        if (domain_name != ""):
+            new_conf.append("domain {0}\nsearch {1}\n".format(domain_name,
+                                                              domain_name))
+        
+        if (controller['fields']['domain_lookups_enabled'] == True):
+            for dns in dns_servers:
+                if (dns['fields']['controller'] == controller['pk']):
+                    ip = dns['fields']['ip']
+                    if (ip != ""):
+                        (r, m) = self.validate_ip(ip)
+                        if not r:
+                            ret_result['err'].append("Name server %s: %s" % (ip, m))
+                            ip = ""
+                    if (ip != ""):
+                        new_conf.append("nameserver {0}\n".format(ip))
+        
+        f = open("/etc/resolv.conf", "r")
+        if (''.join(new_conf) != f.read()):
+            f.close()
+            f = open("/etc/resolv.conf", "w")
+            f.write(''.join(new_conf))
+            changed = True
+
+        f.close()
+        return changed
+
+    def set(self, args_list):
+        # args_list: [controllers, controlleDomainServers, controllerInterfaces]
+        # controllerInterfaces may be empty, which requess no rewrite
+        # of /etc/network/insterfaces
+        ifs_rewrite = False if len(args_list) < 3 else True
+
+        ret_result = {'err': [], 'out': []}
+        controller = json.loads(args_list[0])[0]
+        network_restart = True
+
+        rc_changed = False
+        ni_changed = False
+
+        try:
+            domain_name = controller['fields']['domain_name']
+            new_rc = True
+            if domain_name != "":
+                (r, m) = self.validate_domain(domain_name)
+                if not r:
+                    ret_result['err'].append("Search domain %s: %s"
+                                             % (domain_name, m))
+                    new_rc = False
+
+            if new_rc:
+                rc_changed = self.rewrite_etc_resolve_conf(controller,
+                                                           json.loads(args_list[1]),
+                                                           ret_result)
+            
+            if ifs_rewrite:
+                ni_changed = self.rewrite_etc_network_interfaces(controller,
+                                                                 json.loads(args_list[2]),
+                                                                 ret_result)
+        except Exception, _e:
+            network_restart = False
+            traceback.print_exc()
+
+        # don't restart the network config if resolv.conf was only updated
+        if network_restart and ni_changed:
+            # Kill any dhclients that might be hanging around.  When
+            # switching from dhcp to static config, networking restart
+            # won't kill these since the file has already been
+            # rewritten with a config that doesn't include DHCP.  A
+            # cleaner fix for this is to stop networking before
+            # writing the file and then start it after writing the
+            # file.  Longer-term, it might be better to use
+            # NetworkManager APIs for all of this rather than trying
+            # to manage this config file.
+            k = Popen(["/usr/bin/killall", "dhclient3"],
+                      stdout=PIPE, stderr=PIPE)
+            k.wait()
+            
+            p = Popen(["/usr/sbin/invoke-rc.d",
+                       "networking",
+                       "restart"],
+                       stdout=PIPE, stderr=PIPE)
+            p.wait()
+        
+            if (0 != p.returncode):
+                out = p.stdout.read()
+                ret_result['err'].append("Network restart failed:"
+                                         "%d: %s" % (p.returncode, out))
+
+            # Restart the discover-ip since the controller-interface table has been modified
+            ip = Popen(["/usr/sbin/service",
+                        "discover-ip",
+                        "restart"],
+                        stdout=PIPE, stderr=PIPE)
+
+            # not concerned with error messages from the requested command
+            
+        return ret_result
+
+class DirectNetworkConfig(NetworkConfig):
+    def __init__(self, name="direct_network_config"):
+        NetworkConfig.__init__(self, name)
+
+    def set(self, args_list):
+        gateway = ''
+        ip = ''
+        netmask = ''
+        domain_name = ''
+        dns1 = ''
+        dns2 = ''
+        domain_lookups_enabled = False
+        if args_list[0] == 'static':
+            ip = args_list[1]
+            netmask = args_list[2]
+            gateway = args_list[3]
+            if len(args_list) >= 5:
+                domain_name = args_list[4]
+                if len(args_list) >= 6:
+                    domain_lookups_enabled = True
+                    dns1 = args_list[5]
+                    if len(args_list) >= 7:
+                        dns2 = args_list[6]
+        else:
+            if len(args_list) >= 2:
+                domain_name = args_list[1]
+                if len(args_list) >= 3:
+                    domain_lookups_enabled = True
+                    dns1 = args_list[2]
+                    if len(args_list) >= 4:
+                        dns2 = args_list[3]
+
+        controller_interface=[{'fields' : {'id' : "localhost|ethernet|0", 
+                                          'type' : "ethernet", 'number' : 0, 
+                                          'mode' : args_list[0], 'ip' : ip, 
+                                          'netmask' : netmask, 'controller' : 'localhost'}}]
+        nameservers = []
+        if dns1 != '':
+            nameservers.append({ 'fields' : {'controller' : "localhost", 'priority' : 1, 'ip' : dns1}})
+            if dns2 != '':
+                nameservers.append({ 'fields' : {'controller' : "localhost", 'priority' : 2, 'ip' : dns2}})
+        controller=[{'fields' : {'id' : "localhost", 'domain_name' : domain_name,
+                                 'default_gateway' : gateway, 
+                                 'domain_lookups_enabled' : domain_lookups_enabled}, 'pk' : 'localhost'}]
+        return NetworkConfig.set(self, [json.dumps(controller), json.dumps(nameservers), 
+                              json.dumps(controller_interface)])               
+
+
+class UfwCommand(OsWrapper):
+    def __init__(self, name = "executeufwcommand"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, arg_list):
+        args = arg_list[0].split(" ")
+        self.cmds_lst_for_set = [{'bin_name' : '/usr/sbin/ufw', 'args_lst' : args}]
+        return OsWrapper.set_new(self, [], [[]])
+
+NTP_CONF = """tinker panic 0
+driftfile /var/lib/ntp/ntp.drift
+
+# Enable this if you want statistics to be logged.
+#statsdir /var/log/ntpstats/
+
+statistics loopstats peerstats clockstats
+filegen loopstats file loopstats type day enable
+filegen peerstats file peerstats type day enable
+filegen clockstats file clockstats type day enable
+
+# Specify one or more NTP servers.
+
+# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board
+# on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for
+# more information.
+server %s
+
+# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for
+# details.  The web page <http://support.ntp.org/bin/view/Support/AccessRestrictions>
+# might also be helpful.
+#
+# Note that "restrict" applies to both servers and clients, so a configuration
+# that might be intended to block requests from certain clients could also end
+# up blocking replies from your own upstream servers.
+
+# By default, exchange time with everybody, but don't allow configuration.
+restrict -4 default kod notrap nomodify nopeer noquery
+restrict -6 default kod notrap nomodify nopeer noquery
+
+# Local users may interrogate the ntp server more closely.
+restrict 127.0.0.1
+restrict ::1
+
+# Clients from this (example!) subnet have unlimited access, but only if
+# cryptographically authenticated.
+#restrict 192.168.123.0 mask 255.255.255.0 notrust
+
+
+# If you want to provide time to your local subnet, change the next line.
+# (Again, the address is an example only.)
+#broadcast 192.168.123.255
+
+# If you want to listen to time broadcasts on your local subnet, de-comment the
+# next lines.  Please do this only if you trust everybody on the network!
+#disable auth
+#broadcastclient
+"""
+
+class SetNtpServer(OsWrapper):
+    def __init__(self, name = "setntpserver"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+        ret_result = {'err': [], 'out': []}
+        server = "127.127.1.0"
+        if (len(args_list) > 0 and 
+            args_list[0] is not None and 
+            args_list[0] != ""):
+            server = str(args_list[0])
+        ntpconf = NTP_CONF % server
+        changed = False
+
+        f = open("/etc/ntp.conf", "r")
+        if (''.join(ntpconf) != f.read()):
+            f.close()
+            f = open("/etc/ntp.conf", "w")
+            f.write(''.join(ntpconf))
+            changed = True
+
+        if changed:
+            ntp = Popen(["/usr/sbin/service",
+                        "ntp",
+                        "restart"],
+                        stdout=PIPE, stderr=PIPE)
+        return ret_result
+
+
+class SetTimezone(OsWrapper):
+    def __init__(self, name = "settimezone"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/bin/bash',
+             'args_lst' : ['-c', 'echo "%s" >/etc/timezone' % (str(args_list[0]), )]},
+            {'bin_name' : '/bin/bash',
+             'args_lst' : ['-c', '/usr/sbin/dpkg-reconfigure -f noninteractive tzdata 2>&1']},
+            {'bin_name' : '/sbin/initctl',
+             'args_lst' : ['restart', 'rsyslog', ]},
+        ]
+        return OsWrapper.set_new(self, [], [[], [], []])
+
+
+class UnsetTimezone(OsWrapper):
+    def __init__(self, name = "unsettimezone"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/bin/bash',
+             'args_lst' : ['-c', 'echo "Etc/UTC" >/etc/timezone']},
+            {'bin_name' : '/bin/bash',
+             'args_lst' : ['-c', '/usr/sbin/dpkg-reconfigure -f noninteractive tzdata 2>&1']},
+        ]
+        return OsWrapper.set_new(self, [], [[], []])
+
+class SetSyslogServer(OsWrapper):
+    def __init__(self, name = "setsyslogserver"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/bin/sed',
+             'args_lst' : ['-i', '/^*.* @/d', '/etc/rsyslog.conf']},
+            {'bin_name' : '/bin/echo',
+             'args_lst' : ['*.' + str(args_list[1]) + ' @' + str(args_list[0])], 'stdoutfile' : '/etc/rsyslog.conf'},
+            {'bin_name' : '/sbin/initctl',
+             'args_lst' : ['restart', 'rsyslog']},
+        ]
+        return OsWrapper.set_new(self, [], [[], [], []])
+
+class UnsetSyslogServer(OsWrapper):
+    def __init__(self, name = "unsetsyslogserver"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/bin/sed',
+             'args_lst' : ['-i', '/^*./d', '/etc/rsyslog.conf']},
+            {'bin_name' : '/sbin/initctl',
+             'args_lst' : ['restart', 'rsyslog']}
+        ]
+        return OsWrapper.set_new(self, [], [[], []])
+
+class DateTime(OsWrapper):
+    def __init__(self, name = "getdatetime"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+        # If we're getting or setting the clock then the first argument
+        # should be either 'utc' or 'local' to indicate whether or not to
+        # use local time.
+        # If we're setting the clock there's a second argument which is the
+        # time to set, formatted as shown in set_cmd_args below.
+        set_parts = args_list[1].split(':')
+        set_param = '%2.2s%2.2s%2.2s%2.2s%4.4s.%2.2s' % (
+                        set_parts[1],
+                        set_parts[2],
+                        set_parts[3],
+                        set_parts[4],
+                        set_parts[0],
+                        set_parts[5],
+                        )
+        cmd_args = [str(set_param)]
+        if str(args_list[0]).lower() == 'utc':
+            cmd_args.insert(0, '-u')
+        #date_info = args_list[0]
+        #is_utc = args_list[1]
+        #date_str = "%s:%s:%s:%s:%s:%s:%s"
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/bin/date', 'args_lst' : cmd_args},
+        ]
+        OsWrapper.set_new(self, [], [[]])
+        return self.get(args_list)
+    
+    def get(self, args_list):
+        cmd_args = ['+%Y:%m:%d:%H:%M:%S:%Z']
+        if str(args_list[0]).lower() == 'utc':
+            cmd_args.insert(0, '-u')
+        self.cmds_lst_for_get = [
+            {'bin_name' : '/bin/date', 'args_lst' : cmd_args},
+        ]
+        return OsWrapper.get_new(self, [], [[]])
+        
+class SetControllerId(OsWrapper):
+    def __init__(self, name = "setcontrollerid"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/bin/sed',
+             'args_lst' : ['-i', '/^controller-id=/d', "%s/run/boot-config" % SDN_ROOT]},
+            {'bin_name' : '/bin/bash',
+             'args_lst' : ['-c', 'echo "controller-id=%s" >> %s/run/boot-config' % (
+                                str(args_list[0]), SDN_ROOT)
+                          ]
+             },
+        ]
+        return OsWrapper.set_new(self, [], [[], []])
+
+class HAFailback(OsWrapper):
+    def __init__(self, name = "hafailback"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/bin/touch',
+             'args_lst' : ["%s/force-one-time-health-check-failure" % SDN_ROOT]},
+        ]
+        return OsWrapper.set_new(self, [], [[]])
+
+#class HAFailover(OsWrapper):
+#    def __init__(self, name = "hafailover"):
+#        OsWrapper.__init__(self, name, [], [])
+#    def set(self, args_list):
+#        self.cmds_lst_for_set = [
+#            {'bin_name' : '/bin/bash',
+#             'args_lst' : ["%s/sys/bin/ha-failover.sh" % SDN_ROOT, str(args_list[0])]},
+#        ]
+#        return OsWrapper.set_new(self, [], [[]])
+
+class SetVrrpVirtualRouterId(OsWrapper):
+    def __init__(self, name = "setvrrpvirtualrouterid"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/bin/bash',
+             'args_lst' : ["%s/sys/bin/set-vrrp-virtual-router-id.sh" % SDN_ROOT, str(args_list[0])]},
+        ]
+        return OsWrapper.set_new(self, [], [[]])
+
+
+def write_controller_restarted():
+    """
+    Write the controller started file with the current timestamp + 5 seconds. This will
+    ensure that health check script ignores the state of sdnplatform for 5 seconds
+    from current time
+    """
+    f = open("/var/run/sdnplatform-healthcheck-disabled", "w")
+    # write time converted to int and then string
+    f.write(str(5 + long(time.time())))
+    f.close()
+
+
+class SetStaticFlowOnlyConfig(OsWrapper):
+    def __init__(self, name = "setstaticflowonlyconfig"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+
+        # write the controller started file. do it before actually resetting
+        # so that there is no race condition with health check script
+        try:
+            write_controller_restarted()
+        except Exception, _e:
+            traceback.print_exc()
+
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/bin/touch',
+             'args_lst' : ["%s/feature/staticflowonlyconfig" % SDN_ROOT]},
+            {'bin_name' : '/sbin/initctl',
+             'args_lst' : ['restart', 'sdnplatform']},
+        ]
+        return OsWrapper.set_new(self, [], [[], [], []])
+
+class RestartSDNPlatform(OsWrapper):
+    def __init__(self, name = "restartsdnplatform"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+
+        # write the controller started file. do it before actually resetting
+        # so that there is no race condition with health check script
+        try:
+            write_controller_restarted()
+        except Exception, _e:
+            traceback.print_exc()
+
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/sbin/initctl',
+             'args_lst' : ['restart', 'sdnplatform']},
+        ]
+        return OsWrapper.set_new(self, [], [[]])
+
+class AbortUpgrade(OsWrapper):
+    def __init__(self, name = "abortupgrade"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/opt/sdnplatform/sys/bin/abort_upgrade.sh',
+             'args_lst' : []},
+        ]
+        return OsWrapper.set_new(self, [], [[]])
+
+class SetDefaultConfig(OsWrapper):
+    def __init__(self, name = "setdefaultconfig"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+
+        # write the controller started file. do it before actually resetting
+        # so that there is no race condition with health check script
+        try:
+            write_controller_restarted()
+        except Exception, _e:
+            traceback.print_exc()
+
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/bin/rm',
+             'args_lst' : ['-f', "%s/feature/staticflowonlyconfig" % SDN_ROOT]},
+            {'bin_name' : '/sbin/initctl',
+             'args_lst' : ['restart', 'sdnplatform']},
+            # if there are other configs their flag files need to be deleted here too
+        ]
+        return OsWrapper.set_new(self, [], [[], [], []])
+
+class SetHostname(OsWrapper):
+    def __init__(self, name = "sethostname"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+        hostname = str(args_list[0])
+        self.cmds_lst_for_set = [
+            # replace hostname from /etc/hosts
+            {'bin_name' : '/bin/sed',
+             'args_lst' : ['-i',
+                           r's/^127\.0\.1\.1 .*$$/127.0.1.1 %s/' % hostname,
+                           '/etc/hosts']},
+            # populate /etc/hosts
+            {'bin_name' : '/bin/bash',
+             'args_lst' : ['-c', 'echo "%s" >/etc/hostname' % hostname]},
+            # tell the system about the hostname
+            {'bin_name' : '/bin/hostname',
+             'args_lst' : ['-b', '-F', '/etc/hostname'] },
+        ]
+        return OsWrapper.set_new(self, [], [[], [], [],])
+
+# In PAM, "auth" == authentication (surprise!)
+# XXX roth -- maybe use PAP instead?
+
+# 'sufficient' --> tacacs+ and local authentication are enabled
+AUTHN_TPL = """\
+auth [default=1 success=ignore] pam_succeed_if.so uid >= 10000
+auth sufficient pam_tacplus.so %(servers)s %(secrets)s %(timeout)s service=login protocol=ip login=login
+"""
+
+# In PAM, "account" == authorization
+AUTHZ_TPL = """\
+account [default=1 success=ignore] pam_succeed_if.so uid >= 10000
+account sufficient pam_tacplus.so %(secrets)s %(timeout)s service=login service_av=shell protocol=ip login=login
+"""
+
+# In PAM, "session" == accounting
+ACCT_TPL = """\
+session sufficient pam_tacplus.so %(servers)s %(secrets)s %(timeout)s service=login service_av=shell protocol=ip
+"""
+
+# XXX roth -- keep this in sync with the current release
+# of /etc/pam.d/sshd
+SSHD_TACPLUS_TPL = """\
+# PAM configuration for the Secure Shell service
+
+# Read environment variables from /etc/environment and
+# /etc/security/pam_env.conf.
+auth       required     pam_env.so # [1]
+# In Debian 4.0 (etch), locale-related environment variables were moved to
+# /etc/default/locale, so read that as well.
+auth       required     pam_env.so envfile=/etc/default/locale
+
+# Standard Un*x authentication.
+%(authn)s
+
+# Disallow non-root logins when /etc/nologin exists.
+account    required     pam_nologin.so
+
+# Uncomment and edit /etc/security/access.conf if you need to set complex
+# access limits that are hard to express in sshd_config.
+# account  required     pam_access.so
+
+# Standard Un*x authorization.
+%(authz)s
+
+# Standard Un*x session setup and teardown.
+%(acct)s
+
+# Print the message of the day upon successful login.
+session    optional     pam_motd.so # [1]
+
+# Print the status of the user's mailbox upon successful login.
+session    optional     pam_mail.so standard noenv # [1]
+
+# Set up user limits from /etc/security/limits.conf.
+session    required     pam_limits.so
+
+# Set up SELinux capabilities (need modified pam)
+# session  required     pam_selinux.so multiple
+
+# Standard Un*x password updating.
+@include common-password
+"""
+
+class TacacsPlusConfig(OsWrapper):
+
+    def __init__(self, name="tacacs_plus_config"):
+        OsWrapper.__init__(self, name, [], [])
+        self.config = {}
+        self.hosts = []
+        self.result = dict(err=[], out=[])
+
+    def isEnabled(self):
+        """Is TACACS+ enabled?
+
+        If any of authn/authz/acct is set, *and* there is a non-empty
+        set of TACACS+ hosts, then we should enable the PAM plugin.
+        """
+
+        if (self.hosts 
+            and (self.config['fields']['tacacs_plus_authn']
+                 or self.config['fields']['tacacs_plus_authz']
+                 or self.config['fields']['tacacs_plus_acct'])):
+            return True
+
+        return False
+
+    def disablePamDefault(self):
+        """Disable the default PAM setup.
+
+        This is installed by the initial configuration scripts
+        for the libpam-tacplus DEB.
+        """
+
+        if not os.path.exists("/usr/share/pam-configs/tacplus"):
+            return
+
+        cmd = ("/usr/sbin/pam-auth-update", "--remove", "tacplus",)
+        pipe = Popen(cmd, stdout=PIPE, stderr=PIPE)
+        out, err = pipe.communicate()
+        code = pipe.wait()
+
+        out = (out or "").strip().split("\n")
+        err = (err or "").strip().split("\n")
+
+        if not code:
+            self.result['out'].append("disabled tacplus via pam-auth-update\n")
+        else:
+            self.result['out'].extend([l + "\n" for l in out])
+            self.result['err'].extend([l + "\n" for l in err])
+            self.result['err'].append("pam-auth-update failed\n")
+
+    def disablePam(self):
+        """Disable the TACACS+ PAM plugin."""
+        m = dict(authn="@include common-auth",
+                 authz="@include common-account",
+                 acct="@include common-session")
+        self.writeLocked("/etc/pam.d/sshd", SSHD_TACPLUS_TPL % m)
+
+    def readLocked(self, path):
+
+        fd = open(path, "r")
+
+        fcntl.lockf(fd, fcntl.LOCK_SH)
+        try:
+            buf = fd.read()
+        except Exception, what:
+            fcntl.lockf(fd, fcntl.LOCK_UN)
+            fd.close()
+            self.result['err'].append(str(what) + "\n")
+            self.result['err'].append("cannot read %s\n" % path)
+            return None
+        fcntl.lockf(fd, fcntl.LOCK_UN)
+
+        fd.close()
+
+        return buf
+
+    def writeLocked(self, path, buf, backup=True):
+        
+        if backup:
+            shutil.copy2(path, path + "-")
+
+        fd = open(path, "w")
+
+        fcntl.lockf(fd, fcntl.LOCK_EX)
+        try:
+            fd.write(buf)
+        except Exception, what:
+            fcntl.lockf(fd, fcntl.LOCK_UN)
+            fd.close()
+            self.result['err'].append(str(what) + "\n")
+            self.result['err'].append("cannot write %s\n" % path)
+            return
+        fcntl.lockf(fd, fcntl.LOCK_UN)
+
+        fd.close()
+
+    def enableNss(self):
+        """Enable the NSS plugin."""
+        
+        buf = self.readLocked("/etc/nsswitch.conf")
+        if buf is None: return
+
+        p = buf.find("\npasswd:")
+        q = buf.find("\n", p+8)
+        if p < 0 or q < 0:
+            self.result['err'].append("cannot find passwd entry"
+                                      " in /etc/nsswitch.conf\n")
+            return
+
+        f = buf[p+8:q]
+        if "remoteuser" in f:
+            self.result['out'].append("remoteuser already enabled"
+                                      " in /etc/nssswitch.conf\n")
+            return
+
+        self.result['out'].append("enabling remoteuser"
+                                  " in /etc/nssswitch.conf\n")
+        f = " " + f.strip() + " remoteuser"
+        buf = buf[:p+8] + f + buf[q:]
+
+        self.writeLocked("/etc/nsswitch.conf", buf)
+
+    def disableNss(self):
+        """Disable the NSS plugin."""
+
+        buf = self.readLocked("/etc/nsswitch.conf")
+        if buf is None: return
+        
+        p = buf.find("\npasswd:")
+        q = buf.find("\n", p+8)
+        if p < 0 or q < 0:
+            self.result['err'].append("cannot find passwd entry"
+                                      " in /etc/nsswitch.conf\n")
+            return
+
+        l = buf[p+8:q].strip().split()
+        if "remoteuser" not in l:
+            self.result['out'].append("remoteuser already disabled"
+                                      " in /etc/nssswitch.conf\n")
+            return
+
+        self.result['out'].append("disabling remoteuser"
+                                  " in /etc/nssswitch.conf\n")
+        l.remove("remoteuser")
+        f = " " + " ".join(l)
+        buf = buf[:p+8] + f + buf[q:]
+
+        self.writeLocked("/etc/nsswitch.conf", buf)
+
+    def enablePam(self):
+        """Enable the TACACS+ PAM plugin.
+
+        * construct consolidate server and secret lists
+        * generate a timeout line
+        * pick sufficient/required clauses as indicated by enable
+          flags in the JSON
+
+        See
+        http://tacplus.git.sourceforge.net/git/gitweb.cgi?p=tacplus/tacplus;a=blob_plain;f=README;hb=HEAD
+        """
+        
+        # disable TACACS+ while updating
+        self.disableNss()
+        self.disablePam()
+
+        # XXX roth -- field is 'ip', but since it is the primary key,
+        # it get mapped to 'pk'.  Go figure.
+        def svrClause(h):
+            self.result['out'].append("enabling host %s\n" % h['pk'])
+            return 'server=%s' % h['pk']
+        
+        servers = " ".join([svrClause(h) for h in self.hosts])
+
+        def keyClause(h):
+            """Secret for this host, possibly the global one."""
+            if h['fields']['key']:
+                return "secret=%s" % h['fields']['key']
+            if self.config['fields']['key']:
+                return "secret=%s" % self.config['fields']['key']
+            return ""
+
+        secrets = " ".join([keyClause(h) for h in self.hosts])
+
+        m = dict(servers=servers, secrets=secrets)
+
+        if self.config['fields']['timeout']:
+            m['timeout'] = 'timeout=%s' % self.config['fields']['timeout']
+        else:
+            m['timeout'] = ''
+
+        isLocal = self.config['fields']['local_authn']
+        isTacacs = self.config['fields']['tacacs_plus_authn']
+
+        authn = []
+        if isTacacs:
+            authn.append(AUTHN_TPL % m)
+        if isLocal:
+            authn.append("@include common-auth")
+
+        isLocal = self.config['fields']['local_authz']
+        isTacacs = self.config['fields']['tacacs_plus_authz']
+
+        authz = []
+        if isTacacs:
+            authz.append(AUTHZ_TPL % m)
+        if isLocal:
+            authz.append("@include common-account")
+
+        isTacacs = self.config['fields']['tacacs_plus_acct']
+
+        acct = []
+        if isTacacs:
+            acct.append(ACCT_TPL % m)
+        acct.append("@include common-session")
+
+        # enable userid lookups
+        self.enableNss()
+
+        # write out sshd PAM config as a final step to enable it
+        m = dict(authn="\n".join(authn),
+                 authz="\n".join(authz),
+                 acct="\n".join(acct))
+        self.writeLocked("/etc/pam.d/sshd", SSHD_TACPLUS_TPL % m)
+
+    def set(self, args_list):
+
+        self.config = json.loads(args_list[0])[0]
+        self.hosts = json.loads(args_list[1])
+
+        self.disablePamDefault()
+
+        if not self.isEnabled():
+            try:
+                self.disableNss()
+                self.disablePam()
+                self.result['out'].append('TACACS+ (via PAM) is now disabled\n')
+            except Exception:
+                traceback.print_exc()
+                self.result['err'].append('TACACS+ (via PAM) disable failed\n')
+            return self.result
+
+        # else, enable the PAM module
+        try:
+            self.enableNss()
+            self.enablePam()
+            self.result['out'].append('TACACS+ (via PAM) is now enabled\n')
+        except Exception:
+            # XXX roth -- maybe back out here and *disable* PAM
+            # so that we do not end up with a broken PAM config
+            traceback.print_exc()
+            self.result['err'].append('TACACS+ (via PAM) enable failed\n')
+
+        return self.result
+
+#
+# get_system_version_string
+#
+# Gets the version string of the controller.
+# Reference implementation is in sdncon/rest/views/do_system_version
+#
+def get_system_version_string():
+    version = "SDN OS 1.0 - custom version"
+    try:
+        f = open("%s/release" % SDN_ROOT, 'r')
+        version = f.read()
+        f.close()
+    except:
+        pass
+    return version
+
+#
+# rewrite_etc_snmpd_conf
+#
+# API to rewrite the /etc/snmp/snmpd.conf file based on latest config
+#
+def rewrite_etc_snmpd_conf(community, location, contact, ret_result):
+    """
+    Return True when the /etc/snmp/snmpd.conf is rewritten. Return False 
+    otherwise. The file is rewritten only when the intended new contents
+    is different from the old contents, this is an attempt to not restart
+    the snmp agent unless something really changed.
+    """
+
+    changed = False
+    new_conf = []
+    # start with default configuration of the file
+    new_conf.append("# Default Configuration for the SNMP daemon\n")
+    new_conf.append("# Agent address\n")
+    new_conf.append("agentAddress udp:161,udp6:[::1]:161\n")
+    new_conf.append("# System Object ID\n")
+    new_conf.append("sysObjectID %s\n" % (BSN_ENTERPRISE_OID_CONTROLLER))
+    new_conf.append("# System Description\n")
+    new_conf.append("sysDescr %s\n"%(get_system_version_string()))
+
+    #add community, location, contact information to the file if not there already
+    if community != '':
+        new_conf.append("rocommunity %s\n" % community)
+    if location != '': 
+        new_conf.append("sysLocation %s\n" % location)
+    if contact != '': 
+        new_conf.append("sysContact %s\n" % contact)
+
+    f = open("/etc/snmp/snmpd.conf", "r")
+    if (''.join(new_conf) != f.read()):
+        f.close()
+        f = open("/etc/snmp/snmpd.conf", "w")
+        f.write(''.join(new_conf))
+        changed = True
+
+    f.close()
+
+    return changed
+
+#
+# One of the entry in the snmp server configuration changed
+#
+class SetSnmpServerConfig(OsWrapper):
+    def __init__(self, name = "setsnmpserverconfig"):
+        OsWrapper.__init__(self, name, [], [])
+
+
+    def set(self, args_list):
+        # args_list: [server_enable, community, location, contact, enable_changed]
+        print "SnmpServerConfig Args List: ", args_list
+        server_enable = args_list[0]
+        community = args_list[1]
+        location = args_list[2]
+        contact = args_list[3]
+        enable_changed = args_list[4]
+
+        ret_result = {'err': [], 'out': []}
+
+        try:
+            # rewrite /etc/snmp/snmpd.conf file
+            need_restart = rewrite_etc_snmpd_conf(community, location, contact, ret_result)
+        except Exception, _e:
+            need_restart = False
+            traceback.print_exc()
+
+        if server_enable == 'True' and (need_restart or enable_changed == 'True'):
+            self.cmds_lst_for_set = [
+                # set snmpdrun=yes
+                {'bin_name' : '/bin/sed',
+                 'args_lst' : ['-i', 's/SNMPDRUN=no/SNMPDRUN=yes/',
+                               '/etc/default/snmpd']},
+                # restart snmpd service 
+                {'bin_name' : '/usr/sbin/service',
+                 'args_lst' : ['snmpd', 'restart']},
+            ]
+            return OsWrapper.set_new(self, [], [[], []])
+
+        elif server_enable == 'False' and enable_changed == 'True':
+            self.cmds_lst_for_set = [
+                # set snmpdrun=no
+                {'bin_name' : '/bin/sed',
+                 'args_lst' : ['-i', 's/SNMPDRUN=yes/SNMPDRUN=no/',
+                               '/etc/default/snmpd']},
+                # stop snmpd service 
+                {'bin_name' : '/usr/sbin/service',
+                 'args_lst' : ['snmpd', 'stop']},
+            ]
+            return OsWrapper.set_new(self, [], [[], []])
+
+        return ret_result
+
+
+#
+# The row entry in the snmp server config table was default and deleted
+#
+class UnsetSnmpServerConfig(OsWrapper):
+    def __init__(self, name = "unsetsnmpserverconfig"):
+        OsWrapper.__init__(self, name, [], [])
+
+    def set(self, args_list):
+        # args_list: []
+        ret_result = {'err': [], 'out': []}
+
+        try:
+            # rewrite /etc/snmp/snmpd.conf to default
+            rewrite_etc_snmpd_conf('', '', '', ret_result)
+        except Exception, _e:
+            traceback.print_exc()
+
+        # now stop the server if its there
+        self.cmds_lst_for_set = [
+            # set snmpdrun=no
+            {'bin_name' : '/bin/sed',
+             'args_lst' : ['-i', 's/SNMPDRUN=yes/SNMPDRUN=no/',
+                           '/etc/default/snmpd']},
+            # stop snmpd service 
+            {'bin_name' : '/usr/sbin/service',
+             'args_lst' : ['snmpd', 'stop']},
+        ]
+        return OsWrapper.set_new(self, [], [[], []])
+
+class SetImagesUserSSHKey(OsWrapper):
+    def __init__(self, name = 'setimagesusersshkey'):
+        OsWrapper.__init__(self, name, [], [])
+
+    def set(self, args_list):
+        sshkey = str(args_list[0]) 
+        # cat the ssh key to the file
+        # set the images user shell to be scponly
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/usr/sbin/usermod',
+             'args_lst' : ['-s', '/usr/bin/scponly', 'images']},
+            {'bin_name' : '/bin/echo',
+             'args_lst' : [sshkey], 
+             'stdoutfile' : '/home/images/.ssh/authorized_keys'},
+        ]
+        return OsWrapper.set_new(self, [], [[], []])
+
+class ReloadController(OsWrapper):
+    def __init__(self, name = 'reloadcontroller'):
+        OsWrapper.__init__(self, name, [], [])
+
+    def set(self, args_list):
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/sbin/reboot',
+             'args_list' : []},
+        ]
+        return OsWrapper.set_new(self, [], [[]])
+
+UPGRADE_IMAGE_FILE_PATH = '/tmp/upgrade-images'
+UPGRADE_IMAGE_MANIFEST = '/tmp/upgrade-image-manifest'
+UPGRADE_PACKAGE_DIRECTORY = '/tmp/upgrade-package/'
+
+class ExtractUpgradePkgManifest(OsWrapper):
+    def __init__(self, name = 'extractupgradepkg'):
+        OsWrapper.__init__(self, name, [], [])
+
+    def set(self, args_list):
+        imageName = str(args_list[0])
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/bin/rm',
+             'args_lst' : [UPGRADE_IMAGE_MANIFEST]},
+            {'bin_name' : '/bin/touch',
+             'args_lst' : [UPGRADE_IMAGE_MANIFEST]},
+            {'bin_name' : '/usr/bin/unzip',
+             'args_lst' : ['-p', imageName, 'Manifest'],
+             'stdoutfile' : UPGRADE_IMAGE_MANIFEST},
+        ]
+        return OsWrapper.set_new(self, [], [[], [], []], useShell=False, appendStdOut=False)
+
+    def get(self, args_list):
+        self.cmds_lst_for_get = [
+            {'bin_name' : '/bin/cat',
+             'args_lst': [UPGRADE_IMAGE_MANIFEST]},
+        ]
+        return OsWrapper.get_new(self, [], [[]])
+
+class GetLatestUpgradePkg(OsWrapper):
+    def __init__(self, name = 'getlatestupgradepkg'):
+        OsWrapper.__init__(self, name, [], [])
+
+    # TODO -
+    # This is ghetto, it just finds the last zip
+    # file in the dir. FIX THIS!
+    def get(self, args_list):
+        execStr = 'ls -t /home/images/*.pkg | grep pkg | head -1 > ' + UPGRADE_IMAGE_FILE_PATH
+        self.cmds_lst_for_get = [
+            {'bin_name' : execStr, 
+             'args_lst' : []},
+        ]
+        return OsWrapper.get_new(self, [], [[]], useShell=True)
+
+class CatUpgradeImagesFile(OsWrapper):
+    def __init__(self, name = 'catupgradeimagesfile'):
+        OsWrapper.__init__(self, name, [], [])
+
+    def get(self, args_list):
+        self.cmds_lst_for_get = [
+            {'bin_name' : '/bin/cat',
+             'args_lst' : [UPGRADE_IMAGE_FILE_PATH]},
+        ]
+        return OsWrapper.get_new(self, [], [[]])
+
+class ExecuteUpgradeStep(OsWrapper):
+    def __init__(self, name = 'executeupgradestep'):
+        OsWrapper.__init__(self, name, [], [])
+
+    def get(self, args_list):
+        ret_result = {'err': [], 'out': []}
+        
+        try:
+            manifest = json.loads(exec_os_wrapper("ExtractUpgradePkgManifest", 'get')['out'])
+        except ValueError:
+            ret_result['err'].append("Corrupted manifest!")
+            return ret_result
+
+        stepToExec = None
+        for step in manifest:
+            if step['step'] == int(args_list[0]):
+                stepToExec = step['action']
+                break;
+
+        if stepToExec == None:
+            ret_result['err'].append("Step %s not found in upgrade package manifest!" %
+                str(args_list[0]))
+            return ret_result
+        
+        upgradePkg = args_list[1]
+        stepScript = tempfile.NamedTemporaryFile(delete=False)
+        scriptName = "scripts/%s" % step['action'].strip()
+        step = check_output(["unzip", "-p", upgradePkg, scriptName])
+        stepScript.write(step)
+        stepScript.flush()
+        stepScript.close()
+        os.chmod(stepScript.name, stat.S_IXUSR | stat.S_IWUSR | stat.S_IRUSR)
+
+        try:
+            ret = check_output([stepScript.name] + args_list[1:],
+                               stderr=PIPE)
+            ret_result['out'].append(stripped(ret.strip()))
+        except CalledProcessError, exception:
+            ret_result['err'].append("Error running %s\nreturn code %s\nOutput:\n%s" %
+                    (exception.cmd, exception.returncode, stripped(exception.output)))
+        return ret_result
+
+class CleanupOldUpgradeImages(OsWrapper):
+    def __init__(self, name = 'cleanupoldupgradeimages'):
+        OsWrapper.__init__(self, name, [], [])
+
+    def get(self, args_list):
+        # Removes all the .pkg files execpt for the newest one.
+        # It handles the case where there is only 1 package, we don't delete it.
+        execStr = 'c=`ls /home/images/*.pkg | wc -l`; if [ "$c" -gt 1 ]; then ls -t -r /home/images/*.pkg | head -n -1 | xargs rm; fi'
+        self.cmds_lst_for_get = [
+            {'bin_name' : execStr, 
+             'args_lst' : []},
+        ]
+        return OsWrapper.get_new(self, [], [[]], useShell=True)
+
+class Decommission(OsWrapper):
+    def __init__(self, name = "decommission"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/bin/bash',
+             'args_lst' : ["%s/sys/bin/remove-node.sh" % SDN_ROOT, str(args_list[0])]},
+        ]
+        return OsWrapper.set_new(self, [], [[]])
+
+class DecommissionLocal(OsWrapper):
+    def __init__(self, name = "decommissionlocal"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/bin/bash',
+             'args_lst' : ["%s/sys/bin/remove-node-local.sh" % SDN_ROOT, str(args_list[0])]},
+        ]
+        return OsWrapper.set_new(self, [], [[]])
+
+class ResetBsc(OsWrapper):
+    def __init__(self, name = "resetbsc"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/bin/bash',
+             'args_lst' : ["%s/sys/bin/resetbsc" % SDN_ROOT, '--force']},
+        ]
+        return OsWrapper.set_new(self, [], [[]])
+
+class WriteDataToFile(OsWrapper):
+    def __init__(self, name = 'writedatatofile'):
+        OsWrapper.__init__(self, name, [], [])
+
+    def set(self, args_list):
+        data = str(args_list[0])
+        path = str(args_list[1])
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/bin/touch',
+             'args_lst' : [path]},
+            {'bin_name' : '/bin/echo',
+             'args_lst' : [data], 
+             'stdoutfile' : path},
+        ]
+        return OsWrapper.set_new(self, [], [[], []])
+
+class DiffConfig(OsWrapper):
+    def __init__(self, name = "scpconfig"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/opt/sdnplatform/sys/bin/diff_config.py',
+             'args_lst' : [str(args_list[0]), str(args_list[1])]},
+        ]
+        return OsWrapper.set_new(self, [], [[]])
+
+class RollbackConfig(OsWrapper):
+    def __init__(self, name = "upgradeconfig"):
+        OsWrapper.__init__(self, name, [], [])
+    def set(self, args_list):
+        self.cmds_lst_for_set = [
+            {'bin_name' : '/bin/bash',
+             'args_lst' : ["%s/sys/bin/rollback-config.sh" % SDN_ROOT, str(args_list[0])]},
+        ]
+        return OsWrapper.set_new(self, [], [[]])
+
+def stripped(x):
+    # remove ascii escape
+    return "".join([i for i in x if ord(i) != 27])
+#
+# exec_os_wrapper
+#
+def exec_os_wrapper(obj_type, oper, args_list = None):
+    """
+    Execute the oswrapper.py using sudo(), raising an exception
+    for any stderr output from the executed script
+    """
+    # Safety check; only run if this file exists
+    if not os.path.exists("%s/con" % SDN_ROOT):
+        print "exec_os_wrapper: not an installed controller environment"
+        return {'out' : '', 'err' : ''}
+    if os.path.exists('/etc/not-controller'):
+        # XXX should issue some alert here
+        print "exec_os_wrapper: /etc/not-controller exists"
+        return {'out' : '', 'err' : ''}
+
+    oswrapper = os.path.dirname(__file__) + "/oswrapper.py"
+    full_cmd_string = ["/usr/bin/sudo", oswrapper, obj_type, oper]
+    if args_list:
+        full_cmd_string += [str(arg) for arg in args_list]
+
+    sub_proc_output = Popen(full_cmd_string, shell=False,
+                            stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
+
+    sub_proc_output.wait()
+    stderr = sub_proc_output.stderr.read()
+    stdout = sub_proc_output.stdout.read()
+    returncode = sub_proc_output.returncode
+
+    if returncode:
+        raise Exception("oswrapper: %s %s: exit code %d: %s" %
+                        (obj_type, oper, returncode, stderr))
+    
+    if len(stderr) != 0 and not stderr.isspace():
+        print " ".join(full_cmd_string), stderr
+
+    # ?!?
+    return {'out' : stdout, 'err' : stderr}
+
+
+def main(argv):
+    obj_type_map = {'ExecuteUfwCommand'       : UfwCommand,
+                    'SetNtpServer'            : SetNtpServer,
+                    'SetTimezone'             : SetTimezone,
+                    'UnsetTimezone'           : UnsetTimezone,
+                    'NetworkConfig'           : NetworkConfig,
+                    'SetSyslogServer'         : SetSyslogServer,
+                    'UnsetSyslogServer'       : UnsetSyslogServer,
+                    'DateTime'                : DateTime,
+                    'ControllerId'            : SetControllerId,
+                    'HAFailback'              : HAFailback,
+                    'SetHostname'             : SetHostname,
+                    'SetVrrpVirtualRouterId'  : SetVrrpVirtualRouterId,
+                    'SetStaticFlowOnlyConfig' : SetStaticFlowOnlyConfig,
+                    'SetDefaultConfig'        : SetDefaultConfig,
+                    'TacacsPlusConfig'        : TacacsPlusConfig,
+                    'SetSnmpServerConfig'     : SetSnmpServerConfig,
+                    'UnsetSnmpServerConfig'   : UnsetSnmpServerConfig,
+                    'SetImagesUserSSHKey'     : SetImagesUserSSHKey,
+                    'ReloadController'        : ReloadController,
+                    'ExtractUpgradePkgManifest' : ExtractUpgradePkgManifest,
+                    'GetLatestUpgradePkg'     : GetLatestUpgradePkg,
+                    'CatUpgradeImagesFile'    : CatUpgradeImagesFile,
+                    'ExecuteUpgradeStep'      : ExecuteUpgradeStep,
+                    'DirectNetworkConfig'     : DirectNetworkConfig,
+                    'CleanupOldUpgradeImages' : CleanupOldUpgradeImages,
+                    'RestartSDNPlatform'       : RestartSDNPlatform,
+                    'AbortUpgrade'            : AbortUpgrade,
+                    'Decommission'            : Decommission,
+                    'DecommissionLocal'       : DecommissionLocal,
+                    'RollbackConfig'          : RollbackConfig, 
+                    'DiffConfig'              : DiffConfig,
+                    'ResetBsc'                : ResetBsc,
+                    'WriteDataToFile'         : WriteDataToFile,
+                    }
+    ret_result = {'err': ["insufficient or invalid args"], 'out': []}
+    if len(argv) >= 3:
+        if argv[1] in obj_type_map:
+            obj_type = obj_type_map[argv[1]]
+            x = obj_type()
+            if argv[2] == 'set':
+                ret_result = x.set(argv[3:])
+            elif argv[2] == 'get':
+                ret_result = x.get(argv[3:])
+    
+    # The ret_result entries are lists of strings from the output's of
+    # various commands.
+    print >>sys.stdout, ''.join(ret_result['out'])
+    print >>sys.stderr, ''.join(ret_result['err'])
+
+if __name__ == '__main__':
+    main(sys.argv)
diff --git a/sdncon/controller/tests.py b/sdncon/controller/tests.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/sdncon/controller/tests.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
diff --git a/sdncon/controller/views.py b/sdncon/controller/views.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/sdncon/controller/views.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
diff --git a/sdncon/coreui/__init__.py b/sdncon/coreui/__init__.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/sdncon/coreui/__init__.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
diff --git a/sdncon/coreui/dummy_keyfile b/sdncon/coreui/dummy_keyfile
new file mode 100755
index 0000000..46173df
--- /dev/null
+++ b/sdncon/coreui/dummy_keyfile
@@ -0,0 +1 @@
+67685bfa8762baeb27672d6859e9cea71b319ccb37c0d77fbd8b8448ed33c9650ab5c2141f3b7cad25a3f738305a67103a96a9af7e855fa02d1c06360e2cfa36
diff --git a/sdncon/coreui/img/bsnlogo-l.png b/sdncon/coreui/img/bsnlogo-l.png
new file mode 100755
index 0000000..1a66153
--- /dev/null
+++ b/sdncon/coreui/img/bsnlogo-l.png
Binary files differ
diff --git a/sdncon/coreui/img/bsnlogo-s.png b/sdncon/coreui/img/bsnlogo-s.png
new file mode 100755
index 0000000..afce497
--- /dev/null
+++ b/sdncon/coreui/img/bsnlogo-s.png
Binary files differ
diff --git a/sdncon/coreui/img/bsnlogo.png b/sdncon/coreui/img/bsnlogo.png
new file mode 100755
index 0000000..70b98b5
--- /dev/null
+++ b/sdncon/coreui/img/bsnlogo.png
Binary files differ
diff --git a/sdncon/coreui/img/footer.png b/sdncon/coreui/img/footer.png
new file mode 100755
index 0000000..50d0440
--- /dev/null
+++ b/sdncon/coreui/img/footer.png
Binary files differ
diff --git a/sdncon/coreui/img/gradient.png b/sdncon/coreui/img/gradient.png
new file mode 100755
index 0000000..b096cef
--- /dev/null
+++ b/sdncon/coreui/img/gradient.png
Binary files differ
diff --git a/sdncon/coreui/img/handandsticker2.jpg b/sdncon/coreui/img/handandsticker2.jpg
new file mode 100755
index 0000000..5e18485
--- /dev/null
+++ b/sdncon/coreui/img/handandsticker2.jpg
Binary files differ
diff --git a/sdncon/coreui/img/loading-circle.gif b/sdncon/coreui/img/loading-circle.gif
new file mode 100755
index 0000000..411b115
--- /dev/null
+++ b/sdncon/coreui/img/loading-circle.gif
Binary files differ
diff --git a/sdncon/coreui/models.py b/sdncon/coreui/models.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/sdncon/coreui/models.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
diff --git a/sdncon/coreui/templatetags/__init__.py b/sdncon/coreui/templatetags/__init__.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/sdncon/coreui/templatetags/__init__.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
diff --git a/sdncon/coreui/templatetags/gravatar.py b/sdncon/coreui/templatetags/gravatar.py
new file mode 100755
index 0000000..a39fa2d
--- /dev/null
+++ b/sdncon/coreui/templatetags/gravatar.py
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django import template
+register = template.Library()
+
+from hashlib import md5
+from sdncon.clusterAdmin.utils import isCloudBuild
+
+@register.filter
+def gravatar(email):
+    try:
+        secure = isCloudBuild()
+        options='?d=mm&s=48'
+        url = 'http://www.gravatar.com/avatar/%s.jpg%s'
+        if secure:
+            url = 'https://secure.gravatar.com/avatar/%s.jpg%s'
+        return  url % (md5(email.lower().strip()).hexdigest(), options)
+    except:
+        # Filters must fail silently
+        return '#'
diff --git a/sdncon/coreui/tests.py b/sdncon/coreui/tests.py
new file mode 100755
index 0000000..793e610
--- /dev/null
+++ b/sdncon/coreui/tests.py
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+"""
+This file demonstrates two different styles of tests (one doctest and one
+unittest). These will both pass when you run "manage.py test".
+
+Replace these with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+class SimpleTest(TestCase):
+    def test_basic_addition(self):
+        """
+        Tests that 1 + 1 always equals 2.
+        """
+        self.failUnlessEqual(1 + 1, 2)
+
+__test__ = {"doctest": """
+Another way to test that 1 + 1 is equal to 2.
+
+>>> 1 + 1 == 2
+True
+"""}
+
diff --git a/sdncon/coreui/urls.py b/sdncon/coreui/urls.py
new file mode 100755
index 0000000..423221a
--- /dev/null
+++ b/sdncon/coreui/urls.py
@@ -0,0 +1,29 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.conf.urls.defaults import *
+import os
+
+# Note: Looking for the views for top level tabs? Theya re added automagically in the global urls.py
+
+urlpatterns= patterns('',
+    # Serve static files (for development only - this should be a real webserver for production.)
+    (r'^static/(?P<path>.*)$', 'django.views.static.serve', \
+        {'document_root': os.path.join(os.path.dirname(__file__),'static')}),
+    (r'^img/(?P<path>.*)$', 'django.views.static.serve', \
+        {'document_root': os.path.join(os.path.dirname(__file__),'img')}),
+)
+
diff --git a/sdncon/coreui/views.py b/sdncon/coreui/views.py
new file mode 100755
index 0000000..b7fbdd9
--- /dev/null
+++ b/sdncon/coreui/views.py
@@ -0,0 +1,153 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+#  Views for the core controller UI
+#
+
+from django.shortcuts import render_to_response
+from django.utils import simplejson
+from django.http import HttpResponse
+from django.contrib.auth.decorators import login_required
+from django.contrib.auth.models import User
+from django.template import RequestContext
+from sdncon.apploader import AppLoader, AppLister
+from sdncon.clusterAdmin.utils import conditionally, isCloudBuild
+from sdncon.clusterAdmin.models import Customer, Cluster, CustomerUser
+import os
+
+JSON_CONTENT_TYPE = 'application/json'
+
+# --- View for the root page of any application
+@conditionally(login_required, isCloudBuild())
+def show_application_tabs(request, app):
+    clusterlist = []
+    cus = CustomerUser.objects.all()
+    for cu in cus:
+        if cu.user.username == request.user.username:
+            for cluster in cu.customer.cluster_set.all():
+                clusterlist.append({'customer': cluster.customer.customername,
+                                    'clustername': cluster.clustername,
+                                    'clusterid': unicode(cluster)})
+
+    return render_to_response('coreui/templates/showapp.html', 
+                {'apps':[x for x in AppLoader.getApps() if not hasattr(x,'invisible')],'currentapp':app,'tabs':AppLoader.getApp(app).tabs,'clusterlist':clusterlist, 'isCloudBuild': isCloudBuild()},
+                context_instance=RequestContext(request))
+
+# --- Generic Views
+def embedded_datatable(request, model, options=None, skip_columns=[]): 
+
+    model_name = model.__name__
+    title = model_name + " Table"
+    tablename = model_name+"-embed"
+    table_data = Switch.objects.all()
+
+    # Find headers
+    table_headers = []
+    for field in model._meta.local_fields:
+        table_headers.append(field.name)
+    print table_headers
+
+    # Skip unwanted columns
+    for c in skip_columns:
+        if c in table_headers:
+            table_headers.remove(c)
+
+    # Populate data
+    table_data = []
+    for instance in model.objects.all():
+        table_row = []
+        for field in table_headers:
+            value = instance.__dict__.get(field)
+            table_row.append(value)
+        table_data.append(table_row)
+
+    # Beautify Headers
+    ##TODO ALEX query model info directly, don't use model info list then remove import and delete file
+    #print model_name
+    #if model_name.lower() in model_info_list.model_info_dict:
+    #    print "yes"
+    #    table_headers_c = []
+    #    field_dict = model_info_list.model_info_dict[model_name.lower()]["fields"]
+    #    for h in table_headers:
+    #        h = h.replace("_","-")
+    #        print h, field_dict
+    #        if h in field_dict:
+    #            table_headers_c.append(field_dict[h]['verbose_name'])
+    #        else:
+    #            table_headers_c.append(h)
+    #    table_headers = table_headers_c
+
+    return render_to_response('coreui/templates/datatable-embed.html', {
+        'tabletitle': title,
+        'tablename' : tablename,
+        'tableheaders' : table_headers, 
+        'tabledata' : table_data,
+        'dataTableOptions': options
+    })
+
+def embedded_datatable_from_model(request, model, options=None, skip_columns=[]): 
+    
+    model_name = model.__name__
+    title = model_name + " Table"
+    tablename = model_name+"-embed"
+    table_data = Switch.objects.all()
+    
+    # Find headers
+    table_headers = []
+    for field in model._meta.local_fields:
+        table_headers.append(field.name)
+    print table_headers
+    
+    # Skip unwanted columns
+    for c in skip_columns:
+        if c in table_headers:
+            table_headers.remove(c)
+
+    # Populate data
+    table_data = []
+    for instance in model.objects.all():
+        table_row = []
+        for field in table_headers:
+            value = instance.__dict__.get(field)
+            table_row.append(value)
+        table_data.append(table_row)
+
+    # Beautify Headers
+    print model_name
+    if model_name.lower() in model_info_list.model_info_dict:
+        print "yes"
+        table_headers_c = []
+        field_dict = model_info_list.model_info_dict[model_name.lower()]["fields"]
+        for h in table_headers:
+            h = h.replace("_","-")
+            print h, field_dict
+            if h in field_dict:
+                if 'verbose_name' in field_dict[h]:
+                    table_headers_c.append(field_dict[h]['verbose_name'])
+                else:
+                    table_headers_c.append(h)
+            else:
+                table_headers_c.append(h)
+        table_headers = table_headers_c
+    
+    return render_to_response('coreui/templates/datatable-embed.html', {
+        'tabletitle': title,
+        'tablename' : tablename,
+        'tableheaders' : table_headers, 
+        'tabledata' : table_data,
+        'dataTableOptions': options
+    })
+   
diff --git a/sdncon/extract_model.py b/sdncon/extract_model.py
new file mode 100755
index 0000000..6838352
--- /dev/null
+++ b/sdncon/extract_model.py
@@ -0,0 +1,105 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+#import time
+
+import datetime
+import django.core.management
+
+try:
+    import settings # Assumed to be in the same directory.
+except ImportError:
+    import sys
+    sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
+    sys.exit(1)
+
+django.core.management.setup_environ(settings)
+
+from django.db import models
+from django.db.models.fields import AutoField, BooleanField, IntegerField
+from django.db.models.fields.related import ForeignKey
+
+import sdncon.rest.views
+
+print "# Generated automatically from controller source"
+print "# via tools/extract_model.py date:  %s" % datetime.datetime.now().ctime()
+
+# we iterate over rest_name_dict, limiting CLI access to those models
+# and model fields accessible via rest
+
+rest_map = {}
+for (model, model_info) in sdncon.rest.views.rest_model_info_dict.items():
+    rest_map[model] = {}
+    for (rest_field_name, rest_field_info) in model_info.rest_name_dict.items():
+        django_field_name = rest_field_info.name
+        rest_map[model][django_field_name] = rest_field_name
+
+model_info_dict = {}
+for (model, model_info) in sdncon.rest.views.rest_model_info_dict.items():
+    django_model_class = model_info.model_class 
+    field_info_dict = {}
+    for (rest_field_name, rest_field_info) in model_info.rest_name_dict.items():
+        django_field_name = rest_field_info.name
+        django_field_info = rest_field_info.django_field_info
+        # now that we have the django info and our own rest info, create a field info to dump
+        json_serialize_string = type(django_field_info) not in (AutoField, BooleanField, IntegerField)
+        field_info = {}
+        field_info['json_serialize_string'] = json_serialize_string
+        if django_field_info.verbose_name != django_field_name:
+            # Check if this is a proxy class
+            if type(django_field_info.verbose_name) is str:
+                field_info['verbose-name'] = django_field_info.verbose_name
+        if django_field_info.primary_key == True:
+            field_info['primary_key'] = True
+        if django_field_info.help_text != "":
+            field_info['help_text'] = django_field_info.help_text
+        field_info['null'] = django_field_info.null
+        if type(django_field_info.default) in [int, bool, str]:
+            field_info['default'] = django_field_info.default
+        field_info['type'] = str(type(django_field_info)).split('.')[-1].replace("'>", "")
+        if field_info['type'] == 'AutoField':
+            # Re-label the cassandra compound key for easier consumption
+            if hasattr(django_model_class, 'CassandraSettings'):
+                cassandra_settings = django_model_class.CassandraSettings
+                if hasattr(cassandra_settings, 'COMPOUND_KEY_FIELDS'):
+                    compound_key_fields = cassandra_settings.COMPOUND_KEY_FIELDS
+                    rest_key_fields = [rest_map[model].get(x, x) for x in compound_key_fields]
+                    field_info['compound_key_fields'] = rest_key_fields
+                    field_info['type'] = 'compound-key'
+                    field_info['help_text'] = '#|%s' % \
+                                              '|'.join(rest_key_fields)
+        if field_info['type'] == 'ForeignKey':
+            other_object = django_field_info.rel.to.Rest.NAME
+            if django_field_info.rel.field_name in rest_map[other_object]:
+                field_info['rel_field_name'] = \
+                    rest_map[other_object][django_field_info.rel.field_name]
+            else:
+                field_info['rel_field_name'] = django_field_info.rel.field_name
+            field_info['rel_obj_type'] = django_field_info.rel.to.Rest.NAME
+        if field_info['type'] == 'CharField':
+            field_info['max_length'] = django_field_info.max_length
+        #if django_field_info.validators:
+            #field_info['validators'] = django_field_info.validators
+        #if isinstance(type, django.PositiveIntegerField):
+            #type_name = 'PositiveIntegerField'
+            #print type_name
+
+        field_info_dict[rest_field_name] = field_info
+    model_info_dict[model]={'fields':field_info_dict, 'has_rest_model': True}
+
+import pprint
+pp = pprint.PrettyPrinter(indent=2)
+print "model_info_dict = ",pp.pprint(model_info_dict)
diff --git a/sdncon/manage.py b/sdncon/manage.py
new file mode 100755
index 0000000..3fa99e4
--- /dev/null
+++ b/sdncon/manage.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.core.management import execute_manager
+try:
+    import settings # Assumed to be in the same directory.
+except ImportError:
+    import sys
+    sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
+    sys.exit(1)
+
+if __name__ == "__main__":
+    execute_manager(settings)
diff --git a/sdncon/rest/RestApiTestData.py b/sdncon/rest/RestApiTestData.py
new file mode 100755
index 0000000..f907e5d
--- /dev/null
+++ b/sdncon/rest/RestApiTestData.py
@@ -0,0 +1,84 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+# This i data file for testing Rest APIs
+# This file is read by RestApiTests.py
+
+test_dpid="11:22:33:44:55:66:77:01"
+test_dpid2="11:22:33:44:55:66:77:01"
+test_mac ="11:22:33:44:55:01"
+test_vns_id   ="test_vns_id_1"
+test_flow_entry_name = "test_flow_entry_name"
+test_vns_acl_name = "test_vns_acl"
+test_syncd_config_id = "test_syncd_config_id"
+test_syncd_transport_config_test_data="test_sync_transport_config_id"
+test_syncd_transport_config_name = "test_syncd_transport_cfg_name"
+test_vns_interface_rule_name = "test_vns_intf_rule_name"
+test_vns_interface_name = "test_vns_intf_name"
+test_vns_interface_acl_direction = "in"
+test_vns_interface_acl_id = "test_vns_interface_acl_id"
+test_vns_acl_name_id = test_vns_id+"|"+test_vns_acl_name
+test_vns_acl_entry_type = "ip"
+test_acl_entry_seq_no = "10"
+test_vns_acl_entry_id = test_vns_acl_name_id+"|"+test_acl_entry_seq_no
+test_vns_acl_entry_src_ip="11.22.33.44"
+test_vns_acl_entry_action="deny"
+test_vns_acl_entry_type="deny"
+test_tag_name = "test_tag_name"
+test_tag_value = "test_tag_value"
+test_tag_id = test_vns_id+"|"+test_tag_name+"|"+test_tag_value
+test_tag_mapping_id = test_tag_id+"|"+test_mac
+
+model_switch_test_data={"path":"model/switch", "data":{"dpid":test_dpid}, "id":"dpid"}
+model_host_test_data  ={"path":"model/host",   "data":{"mac":test_mac}, "id":"mac"}
+model_flow_entry_test_data = {"path":"model/flow-entry", "data":{"switch":test_dpid, "name":test_flow_entry_name}, "id":"name"}
+model_vns_definition_test_data = {"path":"model/vns-definition", "data":{"id":test_vns_id}, "id":"id"}
+model_vns_acl_test_data = {"path":"model/vns-access-list", "data":{"vns":test_vns_id, "name":test_vns_acl_name_id}, "id":"name"}
+model_host_network_address_test_data = {"path":"model/host-network-address", \
+    "data":{"id":"ea:81:27:2a:6b:6b-10.0.0.1"}, "id":"id"}
+model_syncd_config_test_data = {"path":"model/syncd-config", "data":{"id":test_syncd_config_id}, "id":"id"}
+model_tag_test_data = {"path":"model/tag", "data":{"id":test_tag_id, \
+    "name":"tagname", "value":"tagvalue", "namespace":test_vns_id}, "id":"id"}
+model_tag_mapping_test_data = {"path":"model/tag-mapping", "data":{"id": test_tag_mapping_id, \
+                               "tag": test_tag_id, "type": "host", "host": test_mac}, "id":"id"}
+model_syncd_transport_config_test_data = {"path":"model/syncd-transport-config", 
+    "data":{"id":"test_syncd_transport_config_test_data", "type":"random1", "args":"test_args", \
+    "config":test_syncd_config_id, "target-cluster":"Testcluster", "name":test_syncd_transport_config_name}, "id":"id"}
+model_syncd_progress_info_test_data = {"path":"model/syncd-progress-info", "data":{"id":test_syncd_config_id}, "id":"id"}
+model_vns_interface_rule_test_data ={"path":"model/vns-interface-rule", \
+    "data":{"id":test_vns_id+"|"+test_vns_interface_rule_name, "vns":test_vns_id}, "id":"id"}
+model_vns_interface_acl_test_data = {"path":"model/vns-interface-access-list", "data":{"id":test_vns_interface_acl_id, \
+    "in-out":test_vns_interface_acl_direction, "vns-interface":test_vns_interface_name, "vns-access-list":test_vns_acl_name_id}, "id":"id"}
+model_vns_acl_entry_test_data = {"path":"model/vns-access-list-entry", \
+    "data":{"id":test_vns_acl_entry_id, "src-ip":test_vns_acl_entry_src_ip, \
+    "action":test_vns_acl_entry_action, "vns-access-list":test_vns_acl_name_id, "type":test_vns_acl_entry_type}, "id":"id"}
+
+test_index=0
+rest_api_test_data = {}
+rest_api_test_data[test_index] = model_switch_test_data ; test_index += 1
+rest_api_test_data[test_index] = model_host_test_data; test_index += 1
+rest_api_test_data[test_index] = model_flow_entry_test_data; test_index += 1
+rest_api_test_data[test_index] = model_vns_definition_test_data; test_index += 1
+rest_api_test_data[test_index] = model_vns_acl_test_data; test_index += 1
+rest_api_test_data[test_index] = model_host_network_address_test_data; test_index += 1
+rest_api_test_data[test_index] = model_syncd_config_test_data; test_index += 1
+rest_api_test_data[test_index] = model_tag_test_data; test_index += 1
+rest_api_test_data[test_index] = model_tag_mapping_test_data; test_index += 1
+rest_api_test_data[test_index] = model_syncd_transport_config_test_data; test_index += 1
+rest_api_test_data[test_index] = model_syncd_progress_info_test_data; test_index += 1
+rest_api_test_data[test_index] = model_vns_interface_rule_test_data; test_index += 1
+rest_api_test_data[test_index] = model_vns_interface_acl_test_data; test_index += 1
+rest_api_test_data[test_index] = model_vns_acl_entry_test_data; test_index += 1
diff --git a/sdncon/rest/__init__.py b/sdncon/rest/__init__.py
new file mode 100755
index 0000000..580a7bb
--- /dev/null
+++ b/sdncon/rest/__init__.py
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from sdncon.rest.config import init_config
+
+init_config()
diff --git a/sdncon/rest/config.py b/sdncon/rest/config.py
new file mode 100755
index 0000000..7c0de5c
--- /dev/null
+++ b/sdncon/rest/config.py
@@ -0,0 +1,219 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.db.models.signals import post_save, post_delete
+import json
+import os
+import traceback
+from django.core import serializers
+import sdncon
+
+# FIXME: This code is not thread-safe!!!
+# Currently we don't run Django with multiple threads so this isn't a problem,
+# but if we were to try to enable threading this code would need to be fixed.
+
+pre_save_instance = None
+config_handlers = []
+config_models = set()
+
+
+def add_config_handler(dependencies, handler):
+    """
+    The dependencies argument is a dictionary where the key is a model
+    (i.e. the actual model, not the name of the mode) and the value of the
+    key is a tuple (or list) of field names whose modification should
+    trigger the config handler. The value can also be None to indicate
+    that the config handler should be triggered when any field in the
+    model is modified.
+    
+    The calling convention of a config handler is:
+    
+    def my_config_handler(op, old_instance, new_instance, modified_fields)
+    
+    The 'op' argument is one of 'INSERT', 'UPDATE' or 'DELETE', corresponding
+    to an insertion, update or deletion of a row in the model.
+    The 'old_instance' argument is the instance of the model before the changes.
+    For an 'INSERT' op, old_instance and modified_fields are both None.
+    The 'new_instance' argument is the instance of the model after the changes.
+    For a 'DELETE' op, new_instance and modified_fields are both None.
+    the 'modified_fields' is a dictionary containing the fields that were changed.
+    The dictionary key is the name of the field and the value is the new value.
+    """
+    assert dependencies != None
+    assert handler != None
+    
+    for model in dependencies.keys():
+        config_models.add(model)
+            
+    config_handlers.append((dependencies, handler))
+
+last_config_state_path = None
+
+def get_last_config_state_path():
+    global last_config_state_path
+    if not last_config_state_path:
+        last_config_state_dir = "%s/run/" % sdncon.SDN_ROOT
+        if not os.path.exists(last_config_state_dir):
+            last_config_state_dir = '/tmp'
+        last_config_state_path = os.path.join(last_config_state_dir, 'last-config-state')
+    return last_config_state_path
+
+def reset_last_config_state():
+    path = get_last_config_state_path()
+    try:
+        os.unlink(path)
+    except Exception, _e:
+        pass
+    
+
+def config_read_state():
+    last_config_state = None
+    f = None
+    try:
+        f = open(get_last_config_state_path(), 'r')
+        last_config_state_text = f.read()
+        last_config_state = json.loads(last_config_state_text)
+    except Exception, _e:
+        pass
+    finally:
+        if f:
+            f.close()
+    return last_config_state
+
+def config_write_state(config_state):
+    f = None
+    try:
+        config_state_text = json.dumps(config_state)
+        f = open(get_last_config_state_path(), 'w')
+        f.write(config_state_text)
+    except Exception, e:
+        print "Error writing last config state: %s" % str(e)
+    finally:
+        if f:
+            f.close()
+
+def config_do_insert(sender, new_instance):
+    for config_handler in config_handlers:
+        dependencies = config_handler[0]
+        if sender in dependencies:
+            handler = config_handler[1]
+            try:
+                handler(op='INSERT', old_instance=None, new_instance=new_instance, modified_fields=None)
+            except Exception, _e:
+                traceback.print_exc()
+                
+def config_do_update(sender, old_instance, new_instance):
+    for config_handler in config_handlers:
+        dependencies = config_handler[0]
+        if sender in dependencies:
+            handler = config_handler[1]
+            modified_fields = {}
+            fields = dependencies.get(sender)
+            if not fields:
+                # If no fields were specified for the model then check all of the fields.
+                fields = [field.name for field in sender._meta.fields]
+                
+            for field in fields:
+                old_value = getattr(old_instance, field)
+                new_value = getattr(new_instance, field)
+                if new_value != old_value:
+                    modified_fields[field] = new_value
+            if modified_fields:
+                try:
+                    handler(op='UPDATE', old_instance=old_instance, new_instance=new_instance, modified_fields=modified_fields)
+                except Exception, _e:
+                    traceback.print_exc()
+
+
+def config_do_delete(sender, instance):
+    for config_handler in config_handlers:
+        dependencies = config_handler[0]
+        if sender in dependencies:
+            handler = config_handler[1]
+            try:
+                handler(op='DELETE', old_instance=instance, new_instance=None, modified_fields=None)
+            except Exception, _e:
+                traceback.print_exc()
+
+def model_instances_equal(instance1, instance2):
+    if instance1 == None:
+        return instance1 == instance2
+    
+    for field in instance1._meta.fields:
+        value1 = field.value_from_object(instance1)
+        value2 = field.value_from_object(instance2)
+        if value1 != value2:
+            return False
+    return True
+
+def config_check_state():
+    from sdncon.controller.notification import do_modify_notification, do_delete_notification
+    last_config_state = config_read_state()
+    try:
+        last_config_instances = last_config_state.get('instances')
+    except Exception, _e:
+        last_config_instances = {}
+    
+    current_config_instances = {}
+    
+    for config_model in config_models:
+        try:
+            serialized_old_instances = json.dumps(last_config_instances.get(config_model.__name__,[]))
+            old_instance_info = serializers.deserialize('json', serialized_old_instances)
+            old_instances = [info.object for info in old_instance_info]
+        except Exception, _e:
+            old_instances = []
+            
+        new_instances = config_model.objects.all()
+        
+        for new_instance in new_instances:
+            for index, old_instance in enumerate(old_instances):
+                if new_instance.pk == old_instance.pk:
+                    if not model_instances_equal(new_instance, old_instance):
+                        config_do_update(config_model, old_instance, new_instance)
+                        do_modify_notification(config_model, new_instance)
+                    del old_instances[index]
+                    break
+            else:
+                config_do_insert(config_model, new_instance)
+                do_modify_notification(config_model, new_instance)
+        
+        for deleted_instance in old_instances:
+            config_do_delete(config_model, deleted_instance)
+            do_delete_notification(config_model, deleted_instance)
+
+        try:
+            serialized_new_instances = serializers.serialize("json", new_instances)
+            current_config_instances[config_model.__name__] = json.loads(serialized_new_instances)
+        except:
+            print 'Failed to serialize', config_model.__name__
+        
+    config_write_state({'instances': current_config_instances})
+
+def config_post_save_handler(sender, **kwargs):
+    if not kwargs['raw'] and (kwargs['using'] == "default") and sender in config_models:
+        config_check_state()
+    
+def config_post_delete_handler(sender, **kwargs):
+    if kwargs['using'] == 'default' and sender in config_models:
+        config_check_state()
+
+def is_config_model(model):
+    return model in config_models
+ 
+def init_config():
+    post_save.connect(config_post_save_handler)
+    post_delete.connect(config_post_delete_handler)
diff --git a/sdncon/rest/jsonview.py b/sdncon/rest/jsonview.py
new file mode 100755
index 0000000..61c7c39
--- /dev/null
+++ b/sdncon/rest/jsonview.py
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.http import HttpResponseForbidden, HttpResponse
+from django.utils.simplejson import JSONEncoder
+from django.utils.encoding import force_unicode
+from django.db.models.base import ModelBase
+from django.utils.simplejson import dumps
+
+class JsonResponse(HttpResponse):
+    """A HttpResponse subclass that creates properly encoded JSON response"""
+
+    def __init__(self, content='', json_opts={},
+                 mimetype="application/json", *args, **kwargs):
+        
+        if content is None: content = []
+        content = serialize_to_json(content,**json_opts)
+        super(JsonResponse,self).__init__(content,mimetype,*args,**kwargs)
+
+class JsonEncoder(JSONEncoder):
+    """A JSONEncoder subclass that also handles querysets and models objects."""
+
+    def default(self,o):
+        # this handles querysets and other iterable types
+        try: iterable = iter(o)
+        except TypeError: pass
+        else: return list(iterable)
+ 
+        # this handlers Models objects
+        try: isinstance(o.__class__,ModelBase)
+        except Exception: pass
+        else: return force_unicode(o)
+ 
+        # delegate the rest to JSONEncoder
+        return super(JsonEncoder,self).default(obj)
+ 
+def serialize_to_json(obj,*args,**kwargs):
+    """A wrapper for dumps with defaults as:
+        ensure_ascii=False
+        cls=JsonEncoder"""
+ 
+    kwargs['ensure_ascii'] = kwargs.get('ensure_ascii', False)
+    kwargs['cls'] = kwargs.get('cls', JsonEncoder)
+    return dumps(obj,*args,**kwargs)
+
+def as_kwargs(qdict):
+    kwargs = {}
+    for k,v in qdict.items():
+        kwargs[str(k)] = v
+    return kwargs
diff --git a/sdncon/rest/models.py b/sdncon/rest/models.py
new file mode 100755
index 0000000..436a90e
--- /dev/null
+++ b/sdncon/rest/models.py
@@ -0,0 +1,26 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.db import models
+from django.contrib.auth.models import User
+# Create your models here.
+
+class UserData(models.Model):
+    user = models.ForeignKey(User, null=True)
+    name = models.CharField(max_length=256)
+    content_type = models.CharField(max_length=128)
+    binary = models.BooleanField()
+    data = models.TextField()
diff --git a/sdncon/rest/poll.py b/sdncon/rest/poll.py
new file mode 100755
index 0000000..bfd0573
--- /dev/null
+++ b/sdncon/rest/poll.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+"""Polling interface for the polling services setup by the rest API"""
+
+import sys, os, time, random, json
+
+from packetstreamer import PacketStreamer
+from packetstreamer.ttypes import *
+
+from thrift import Thrift
+from thrift.transport import TSocket
+from thrift.transport import TTransport
+from thrift.protocol import TBinaryProtocol
+
+def sample_func(request, environ):
+    data = {
+        'pid': os.getpid(),
+        'random': int(random.random()*100),
+    }
+
+    return {
+        'status':    '200 OK',
+        'body':      json.dumps(data),
+        'headers':   [('Content-type', 'application/json')], # list of tuples
+    }
+
+def getPackets_func(request, environ, sessionid):
+    retData = {}
+
+    try:
+        # Make socket
+        transport = TSocket.TSocket('localhost', 9090)
+        # Buffering is critical. Raw sockets are very slow
+        transport = TTransport.TFramedTransport(transport)
+        # Wrap in a protocol
+        protocol = TBinaryProtocol.TBinaryProtocol(transport)
+        # Create a client to use the protocol encoder
+        client = PacketStreamer.Client(protocol)
+        # Connect!
+        transport.open()
+
+        packets = client.getPackets(sessionid)
+
+        # Close!
+        transport.close()
+
+        retData = {
+          'status':    '200 OK',
+          'body':       json.dumps(packets),
+          'headers':    [('Content-type', 'application/json')], # list of tuples
+        }
+
+    except Thrift.TException, tx:
+        retData = {
+          'status':    '500 Internal Server Error',
+          'body':      'error: %s'%tx.message,
+          'headers':   [('Content-type', 'application/json')], # list of tuples
+        }
+
+    return retData
+
+# The polling service
+#   The service is driven by the urlpatterns tuples that list the specific function
+#   to use for a matching pattern in URL. The pattern should not include initial '^/poll'.
+#   For Example:
+#     (r'^/sample', sample_func)
+#from sdncon.rest.poll import sample_func
+urlpatterns = [
+    (r'^/packets/(?P<sessionid>[A-Za-z0-9_.\-]+)/?$', getPackets_func),
+    (r'^/sample', sample_func)
+]
+
+import re, wsgiref.util
+
+def compile_patterns(urlpatterns):
+    return map(lambda pat: (re.compile(pat[0]), pat[1]), urlpatterns)
+
+def main(environ, start_response):
+    patterns = compile_patterns(urlpatterns)
+    request = environ['PATH_INFO']
+    response = None
+    status, body = '404 Not Found', 'Sorry, the requested resource "%s" was not found."' % request
+    headers = []
+    for (pat, func) in patterns:
+        m = pat.match(request)
+        if m:
+            args = m.groups()
+            if args:
+                response = func(request, environ, *args)
+            else:
+                response = func(request, environ)
+
+            status, body = response['status'], response['body']
+            if 'headers' in response:
+                headers.extend(response['headers'])
+            break
+    if 'Cache-Control' not in headers:
+        headers.append(('Cache-Control', 'no-cache'))
+    if 'Content-type' not in headers:
+         headers.append(('Content-type', 'text/plain'))
+    if 'Content-Length' not in headers:
+         headers.append(('Content-Length', str(len(body))))
+    start_response(status, headers)
+    return [body]
+
+if __name__ == "__main__":
+    def start_response(x, y):
+        print 'Status:', x
+        print 'Headers:', y
+
+    print 'Sample', sample_func(None, None)
+    print 'Response:', main({'PATH_INFO':'/sample/100'}, start_response)
+    print 'Response:', main({'PATH_INFO':'/xsample/100'}, start_response)
diff --git a/sdncon/rest/tests.py b/sdncon/rest/tests.py
new file mode 100755
index 0000000..7430831
--- /dev/null
+++ b/sdncon/rest/tests.py
@@ -0,0 +1,648 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.core.validators import validate_ipv4_address, MinValueValidator
+from django.db import models
+from django.forms import ValidationError
+from django.test import TestCase, Client
+from django.utils import simplejson
+import copy
+import urllib
+import urllib2
+from sdncon.rest.validators import validate_mac_address, RangeValidator, ChoicesValidator
+from sdncon.rest.config import add_config_handler, reset_last_config_state, model_instances_equal
+
+# These are the test models used in the unit tests
+# When running the unit tests, syncdb looks for model definitions
+# in this file (i.e. tests.py), so these will be in the complete
+# list of models used by the REST code
+
+class RestTestModel(models.Model):
+    name = models.CharField(max_length=32, primary_key=True)
+    enabled = models.BooleanField()
+    min = models.IntegerField(validators=[MinValueValidator(100)])
+    range = models.IntegerField(validators=[RangeValidator(10,100)])
+    internal = models.CharField(max_length=24,default='foo')
+    ip = models.IPAddressField(validators=[validate_ipv4_address])
+    mac = models.CharField(max_length=20, validators=[validate_mac_address])
+    ratio = models.FloatField()
+    COLOR_CHOICES = (
+        ('red', 'Dark Red'),
+        ('blue', 'Navy Blue'),
+        ('green', 'Green'),
+        ('white', 'Ivory White')
+    )
+    color = models.CharField(max_length=20, validators=[ChoicesValidator(COLOR_CHOICES)])
+    
+    def clean(self):
+        # This is just a dummy check for testing purposes. Typically you'd only
+        # use the model-level clean function for validating things across multiple fields
+        if self.range == 50:
+            raise ValidationError("Dummy model-level validation failure.")
+    
+    class Rest:
+        NAME = 'rest-test'
+        FIELD_INFO = ({'name':'internal', 'private': True},)
+
+class RestTestTagModel(models.Model):
+    rest_test = models.ForeignKey(RestTestModel)
+    name = models.CharField(max_length=32)
+    value = models.CharField(max_length=256)
+    
+    class Rest:
+        NAME = 'rest-test-tag'
+        FIELD_INFO = ({'name':'rest_test', 'rest_name':'rest-test'},)
+        
+class RestTestRenamedFieldModel(models.Model):
+    test = models.CharField(max_length=16,primary_key=True)
+    
+    class Rest:
+        NAME = 'rest-test-renamed'
+        FIELD_INFO = ({'name':'test', 'rest_name':'renamed'},)
+        
+class RestDisabledModel(models.Model):
+    dummy = models.CharField(max_length=32)
+
+class RestCompoundKeyModel(models.Model):
+    name = models.CharField(max_length=32)
+    index = models.IntegerField()
+    extra = models.CharField(max_length=32, default='dummy')
+    
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ['name', 'index']
+        
+    class Rest:
+        NAME = 'rest-compound-key'
+        
+#############################################################################
+# These are some client-side utility functions for getting, putting, deleting
+# data using the REST API
+#############################################################################
+
+def construct_rest_url(path, query_params=None):
+    url = 'http://localhost:8000/rest/v1/%s/' % path
+    if query_params:
+        url += '?'
+        url += urllib.urlencode(query_params)
+    return url
+
+def get_rest_data(type, query_param_dict=None):
+    url = construct_rest_url(type, query_param_dict)
+    request = urllib2.Request(url)
+    response = urllib2.urlopen(request)
+    response_text = response.read()
+    obj = simplejson.loads(response_text)
+    return obj
+
+def put_rest_data(obj, type, query_param_dict=None):
+    url = construct_rest_url(type, query_param_dict)
+    post_data = simplejson.dumps(obj)
+    request = urllib2.Request(url, post_data, {'Content-Type':'application/json'})
+    request.get_method = lambda: 'PUT'
+    response = urllib2.urlopen(request)
+    return response.read()
+
+def delete_rest_data(type, query_param_dict=None):
+    url = construct_rest_url(type, query_param_dict)
+    request = urllib2.Request(url)
+    request.get_method = lambda: 'DELETE'
+    response = urllib2.urlopen(request)
+    return response.read()
+
+def test_construct_rest_url(path, query_params=None):
+    url = '/rest/v1/%s/' % path
+    if query_params:
+        url += '?'
+        url += urllib.urlencode(query_params)
+    return url
+
+def test_construct_rest_model_url(path, query_params=None):
+    return test_construct_rest_url('model/' + path, query_params)
+    
+def test_get_rest_model_data(type, query_params=None):
+    url = test_construct_rest_model_url(type,query_params)
+    c = Client()
+    response = c.get(url)
+    return response
+
+def test_put_rest_model_data(obj, type, query_params=None):
+    url = test_construct_rest_model_url(type, query_params)
+    data = simplejson.dumps(obj)
+    c = Client()
+    response = c.put(url , data, 'application/json')
+    return response
+
+def test_delete_rest_model_data(type, query_params=None):
+    url = test_construct_rest_model_url(type, query_params)
+    c = Client()
+    response = c.delete(url)
+    return response
+
+def get_sorted_list(data_list, key_name, create_copy=False):
+    if create_copy:
+        data_list = copy.deepcopy(data_list)
+    if key_name:
+        key_func = lambda item: item.get(key_name)
+    else:
+        key_func = lambda item: item[0]
+    data_list.sort(key = key_func)
+    return data_list
+
+#############################################################################
+# The actual unit test classes
+#############################################################################
+
+class BasicFunctionalityTest(TestCase):
+    
+    REST_TEST_DATA = [
+        {'name':'foobar','enabled':True,'min':100,'range':30,'ip':'192.168.1.1','mac':'00:01:22:34:56:af','ratio':4.56,'color':'red'},
+        {'name':'sdnplatform','enabled':False,'min':400,'range':45,'ip':'192.168.1.2','mac':'00:01:22:CC:56:DD','ratio':8.76,'color':'green'},
+        {'name':'foobar2','enabled':True,'min':1000,'range':100,'ip':'192.168.1.3','mac':'00:01:22:34:56:af','ratio':1,'color':'white'},
+    ]
+    
+    REST_TEST_TAG_DATA = [
+        {'id':'1','rest-test':'foobar','name':'one','value':'testit'},
+        {'id':'2','rest-test':'foobar','name':'two','value':'test2'},
+        {'id':'3','rest-test':'sdnplatform','name':'three','value':'three'},
+    ]
+    
+    def setUp(self):
+        # Create the RestTestModel instances
+        rest_test_list = []
+        for rtd in self.REST_TEST_DATA:
+            rt = RestTestModel(**rtd)
+            rt.save()
+            rest_test_list.append(rt)
+        
+        # Create the RestTestTagModel instances
+        for rttd in self.REST_TEST_TAG_DATA:
+            rttd_init = rttd.copy()
+            for rt in rest_test_list:
+                if rt.name == rttd['rest-test']:
+                    del rttd_init['rest-test']
+                    rttd_init['rest_test'] = rt
+                    break
+            else:
+                raise Exception('Invalid initialization data for REST unit tests')
+            rtt = RestTestTagModel(**rttd_init)
+            rtt.save()
+        
+        rtrf = RestTestRenamedFieldModel(test='test')
+        rtrf.save()
+        
+        # Create the RestDisabledModel instance. We're only going to test that
+        # we can't access this model via the REST API, so we don't need to keep
+        # track of the data used for the instance
+        #rdm = RestDisabledModel(dummy='dummy')
+        #rdm.save()
+    
+    def check_rest_test_data_result(self, data_list, expected_data_list, message=None):
+        data_list = get_sorted_list(data_list, 'name', True)
+        expected_data_list = get_sorted_list(expected_data_list, 'name', True)
+        self.assertEqual(len(data_list), len(expected_data_list), message)
+        for i in range(len(data_list)):
+            data = data_list[i]
+            expected_data = expected_data_list[i]
+            self.assertEqual(data['name'], expected_data['name'], message)
+            self.assertEqual(data['enabled'], expected_data['enabled'], message)
+            self.assertEqual(data['min'], expected_data['min'], message)
+            self.assertEqual(data['range'], expected_data['range'], message)
+            self.assertEqual(data['ip'], expected_data['ip'], message)
+            self.assertEqual(data['mac'], expected_data['mac'], message)
+            self.assertAlmostEqual(data['ratio'], expected_data['ratio'], 7, message)
+            self.assertEqual(data['color'], expected_data['color'], message)
+    
+    def check_rest_test_tag_data_result(self, data_list, expected_data_list, message=None):
+        data_list = get_sorted_list(data_list, 'name', True)
+        expected_data_list = get_sorted_list(expected_data_list, 'name', True)
+        self.assertEqual(len(data_list), len(expected_data_list), message)
+        for i in range(len(data_list)):
+            data = data_list[i]
+            expected_data = expected_data_list[i]
+            self.assertEqual(str(data['id']), expected_data['id'], message)
+            self.assertEqual(data['rest-test'], expected_data['rest-test'], message)
+            self.assertEqual(data['name'], expected_data['name'], message)
+            self.assertEqual(data['value'], expected_data['value'], message)
+            
+    def test_put_one(self):
+        test_put_rest_model_data({'min':200,'color':'white'}, 'rest-test/foobar')
+        response = test_get_rest_model_data('rest-test')
+        data = simplejson.loads(response.content)
+        rtd_copy = copy.deepcopy(self.REST_TEST_DATA)
+        rtd_copy[0]['min'] = 200
+        rtd_copy[0]['color'] = 'white'
+        self.check_rest_test_data_result(data, rtd_copy)
+        
+    def test_put_query(self):
+        test_put_rest_model_data({'min':200,'color':'white'}, 'rest-test', {'enabled':True})
+        response = test_get_rest_model_data('rest-test')
+        data = simplejson.loads(response.content)
+        rtd_copy = copy.deepcopy(self.REST_TEST_DATA)
+        for rtd in rtd_copy:
+            if rtd['enabled']:
+                rtd['min'] = 200
+                rtd['color'] = 'white'
+        self.check_rest_test_data_result(data, rtd_copy)
+    
+    def test_create_one(self):
+        rtd_copy = copy.deepcopy(self.REST_TEST_DATA)
+        create_rtd = rtd_copy[0].copy()
+        create_rtd['name'] = 'test-create'
+        rtd_copy.append(create_rtd)
+        test_put_rest_model_data(create_rtd, 'rest-test')
+        response = test_get_rest_model_data('rest-test')
+        data = simplejson.loads(response.content)
+        self.check_rest_test_data_result(data, rtd_copy)
+    
+    def test_create_many(self):
+        rtd_copy = copy.deepcopy(self.REST_TEST_DATA)
+        create_rtd1 = rtd_copy[0].copy()
+        create_rtd1['name'] = 'test-create1'
+        create_rtd1['min'] = 2000
+        rtd_copy.append(create_rtd1)
+        create_rtd2 = rtd_copy[0].copy()
+        create_rtd2['name'] = 'test-create2'
+        create_rtd1['min'] = 4000
+        rtd_copy.append(create_rtd2)
+        test_put_rest_model_data([create_rtd1,create_rtd2], 'rest-test')
+        response = test_get_rest_model_data('rest-test')
+        data = simplejson.loads(response.content)
+        self.check_rest_test_data_result(data, rtd_copy)
+        
+    def test_get(self):
+        RTD = self.REST_TEST_DATA
+        RTTD = self.REST_TEST_TAG_DATA
+        GET_TEST_VECTORS = (
+            #model_name, query_params, expected_data
+            ('rest-test', None, RTD, 'Failure getting all rest-test instances'),
+            ('rest-test-tag', None, RTTD, 'Failure getting all rest-test-tag instances'),
+            ('rest-test/foobar', None, RTD[0], 'Failure getting single rest-test instance by URL'),
+            ('rest-test', {'name':'foobar'}, [RTD[0]], 'Failure querying for single rest-test instance'),
+            ('rest-test', {'name':'foobar','nolist':True}, RTD[0], 'Failure querying for single rest-test instance using nolist'),
+            ('rest-test', {'enabled':True}, [RTD[0],RTD[2]], 'Failure querying for multiple rest-test instances'),
+            ('rest-test', {'name__startswith':'foobar'}, [RTD[0],RTD[2]], 'Failure querying for multiple rest-test instances using startswith'),
+            ('rest-test', {'orderby':'ratio'}, [RTD[2],RTD[0],RTD[1]], 'Failure querying with ascending orderby'),
+            ('rest-test', {'orderby':'-ratio'}, [RTD[1],RTD[0],RTD[2]], 'Failure querying with descending orderby'),
+            ('rest-test', {'orderby':'enabled,-ratio'}, [RTD[1],RTD[0],RTD[2]], 'Failure querying with multi-field orderby'),
+            ('rest-test-tag', {'rest-test':'foobar'}, [RTTD[0],RTTD[1]], 'Failure querying by ForeignKey value'),
+            ('rest-test-tag', {'rest-test__startswith':'foo'}, [RTTD[0],RTTD[1]], 'Failure querying by ForeignKey value'),
+            ('rest-test-tag', {'rest-test__contains':'swi'}, [RTTD[2]], 'Failure querying by ForeignKey value'),
+        )
+        
+        for model_name, query_params, expected_data, message in GET_TEST_VECTORS:
+            response = test_get_rest_model_data(model_name, query_params)
+            data = simplejson.loads(response.content)
+            #print model_name
+            #self.check_rest_test_data_result(data, expected_data, message)
+            if type(data) is not list:
+                data = [data]
+                #data = get_sorted_list(data, 'name', False)
+            if type(expected_data) is not list:
+                expected_data = [expected_data]
+                #expected_data = get_sorted_list(expected_data, 'name', True)
+            if model_name.startswith('rest-test-tag'):
+                self.check_rest_test_tag_data_result(data, expected_data, message)
+            else:
+                self.check_rest_test_data_result(data, expected_data, message)
+            
+    def test_renamed_field(self):
+        response = test_get_rest_model_data('rest-test-renamed/test')
+        self.assertEqual(response.status_code,200)
+        data = simplejson.loads(response.content)
+        self.assertEqual(data['renamed'], 'test')
+        
+    def test_delete_one(self):
+        test_delete_rest_model_data('rest-test/foobar')
+        response = test_get_rest_model_data('rest-test')
+        data = simplejson.loads(response.content)
+        self.check_rest_test_data_result(data, self.REST_TEST_DATA[1:])
+    
+    def test_delete_query(self):
+        test_delete_rest_model_data('rest-test', {'name__startswith':'foobar'})
+        response = test_get_rest_model_data('rest-test')
+        data = simplejson.loads(response.content)
+        self.check_rest_test_data_result(data, [self.REST_TEST_DATA[1]])
+    
+    def test_delete_all(self):
+        test_delete_rest_model_data('rest-test')
+        response = test_get_rest_model_data('rest-test')
+        data = simplejson.loads(response.content)
+        self.assertEqual(len(data),0)
+
+class NegativeTest(TestCase):
+    
+    def test_invalid_model_name(self):
+        response = test_get_rest_model_data('foobar')
+        self.assertEqual(response.status_code,400)
+        response_obj = simplejson.loads(response.content)
+        self.assertEqual(response_obj['error_type'],'RestInvalidDataTypeException')
+        
+    def test_resource_not_found(self):
+        response = test_get_rest_model_data('rest-test/foobar')
+        self.assertEqual(response.status_code,404)
+        response_obj = simplejson.loads(response.content)
+        self.assertEqual(response_obj['error_type'],'RestResourceNotFoundException')
+
+    def test_invalid_orderby(self):
+        response = test_get_rest_model_data('rest-test', {'orderby':'foobar'})
+        self.assertEqual(response.status_code,400)
+        response_obj = simplejson.loads(response.content)
+        self.assertEqual(response_obj['error_type'],'RestInvalidOrderByException')
+    
+    def test_hidden_model(self):
+        response = test_get_rest_model_data('restdisabledmodel')
+        self.assertEqual(response.status_code,400)
+        response_obj = simplejson.loads(response.content)
+        self.assertEqual(response_obj['error_type'],'RestInvalidDataTypeException')
+
+class ValidationTest(TestCase):
+    
+    DEFAULT_DATA = {'name':'foobar','enabled':True,'min':100,'range':30,'ip':'192.168.1.1','mac':'00:01:22:34:56:af','ratio':4.56,'color':'red'}
+    TEST_VECTORS = (
+        #update-dict, error-type, error-messgae
+        ({'min':99}, ['min'],'Min value validation failed'),
+        ({'range':8}, ['range'],'Min range validation failed'),
+        ({'range':2000}, ['range'],'Max range validation failed'),
+        ({'range':50}, None,'Model-level clean validation failed'),
+        ({'mac':'00:01:02:03:05'}, ['mac'],'Too short MAC address validation failed'),
+        ({'mac':'00:01:02:03:05:99:45'}, ['mac'],'Too long MAC address validation failed'),
+        ({'mac':'00,01,02,03,05,99'}, ['mac'],'MAC address separator char validation failed'),
+        ({'mac':'0r:01:02:03:05:99'}, ['mac'],'MAC address character validation failed'),
+        ({'mac':'123:01:02:03:05:99'}, ['mac'],'MAC address byte length validation failed'),
+        ({'color':'purple'}, ['color'],'Choices validation failed'),
+        ({'ip':'foobar'}, ['ip'], 'Invalid IP address char validation failed'),
+        ({'ip':'192.168.1'}, ['ip'], 'Too short IP address char validation failed'),
+        ({'ip':'192.168.1.0.5'}, ['ip'], 'Too long IP address char validation failed'),
+        ({'ip':'192,168,1,0'}, ['ip'], 'IP address separator char validation failed'),
+        ({'ip':'256.168.1.0'}, ['ip'], 'Out of range IP address byte validation failed'),
+        ({'min':99, 'ip':'256.168.1.0'}, ['min', 'ip'], 'Multiple field validation failed'),
+    )
+    
+    def check_response(self, response, invalid_fields, message):
+        self.assertEqual(response.status_code,400)
+        response_obj = simplejson.loads(response.content)
+        self.assertEqual(response_obj['error_type'], 'RestValidationException', message)
+        if invalid_fields:
+            self.assertEqual(response_obj.get('model_error'), None)
+            field_errors = response_obj.get('field_errors')
+            self.assertNotEqual(field_errors, None)
+            self.assertEqual(len(invalid_fields), len(field_errors), message)
+            for field_name in field_errors.keys():
+                self.assertTrue(field_name in invalid_fields, message)
+        else:
+            self.assertEqual(response_obj.get('field_errors'), None)
+            self.assertNotEqual(response_obj.get('model_error'), None)
+        # FIXME: Maybe check the description here too?
+        
+    def test_create_validation(self):
+        for test_data, invalid_fields, message in self.TEST_VECTORS:
+            data = self.DEFAULT_DATA.copy()
+            for name, value in test_data.items():
+                data[name] = value
+            put_response = test_put_rest_model_data(data, 'rest-test')
+            self.check_response(put_response, invalid_fields, message)
+            
+    def test_update_validation(self):
+        # First add an instance with the default data and check that it's OK
+        put_response = test_put_rest_model_data(self.DEFAULT_DATA, 'rest-test')
+        self.assertEqual(put_response.status_code,200)
+        
+        for test_data, invalid_fields, message in self.TEST_VECTORS:
+            put_response = test_put_rest_model_data(test_data, 'rest-test/foobar')
+            self.check_response(put_response, invalid_fields, message)
+
+
+class ConfigHandlerTest(TestCase):
+
+    TEST_DATA = {'name':'foobar','enabled':True,'min':100,'range':30,'ip':'192.168.1.1','mac':'00:01:22:34:56:af','ratio':4.56,'color':'red'}
+    
+    test_op = None
+    test_old_instance = None
+    test_new_instance = None
+    test_modified_fields = None
+    
+    @staticmethod
+    def reset_config_handler():
+        ConfigHandlerTest.test_op = None
+        ConfigHandlerTest.test_old_instance = None
+        ConfigHandlerTest.test_new_instance = None
+        ConfigHandlerTest.test_modified_fields = None
+    
+    @staticmethod
+    def config_handler(op, old_instance, new_instance, modified_fields):
+        ConfigHandlerTest.test_op = op
+        ConfigHandlerTest.test_old_instance = old_instance
+        ConfigHandlerTest.test_new_instance = new_instance
+        ConfigHandlerTest.test_modified_fields = modified_fields
+    
+    def check_config_handler(self, expected_op, expected_old_instance, expected_new_instance, expected_modified_fields):
+        self.assertEqual(ConfigHandlerTest.test_op, expected_op)
+        self.assertTrue(model_instances_equal(ConfigHandlerTest.test_old_instance, expected_old_instance))
+        self.assertTrue(model_instances_equal(ConfigHandlerTest.test_new_instance, expected_new_instance))
+        self.assertEqual(ConfigHandlerTest.test_modified_fields, expected_modified_fields)
+        
+    def test_config(self):
+        reset_last_config_state()
+        # Install the config handler
+        field_list = ['internal', 'min', 'mac']
+        add_config_handler({RestTestModel: field_list}, ConfigHandlerTest.config_handler)
+        
+        # Check that config handler is triggered on an insert
+        ConfigHandlerTest.reset_config_handler()
+        test = RestTestModel(**self.TEST_DATA)
+        test.save()
+        self.check_config_handler('INSERT', None, test, None)
+        
+        # Check that config handler is triggered on an update
+        ConfigHandlerTest.reset_config_handler()
+        expected_old = RestTestModel.objects.get(pk='foobar')
+        test.internal = 'check'
+        test.min = 125
+        test.save()
+        self.check_config_handler('UPDATE', expected_old, test, {'internal': 'check', 'min': 125})
+        
+        # Check that config handler is not triggered on an update to a field that
+        # it's not configured to care about
+        ConfigHandlerTest.reset_config_handler()
+        test.max = 500
+        test.save()
+        self.check_config_handler(None, None, None, None)
+        
+        # Check that config handler is triggered on a delete
+        ConfigHandlerTest.reset_config_handler()
+        test.delete()
+        # delete() clears the pk which messes up the instance
+        # comparison logic in check_config_handler, so we hack
+        # it back to the value it had before the delete
+        test.name = 'foobar'    
+        self.check_config_handler('DELETE', test, None, None)
+
+
+class CompoundKeyModelTest(TestCase):
+    
+    TEST_DATA = [
+        {'name': 'foo', 'index': 3},
+        {'name': 'foo', 'index': 7},
+        {'name': 'bar', 'index': 2, 'extra': 'abc'},
+        {'name': 'bar', 'index': 4, 'extra': 'test'},
+    ]
+    
+    def setUp(self):
+        for data in self.TEST_DATA:
+            test_put_rest_model_data(data, 'rest-compound-key')
+    
+    def check_query_results(self, actual_results, expected_results):
+        self.assertEqual(len(actual_results), len(expected_results))
+        actual_results = get_sorted_list(actual_results, 'id', False)
+        expected_results = copy.deepcopy(expected_results)
+        for expected_result in expected_results:
+            expected_result['id'] = expected_result['name'] + '|' + str(expected_result['index'])
+        expected_results = get_sorted_list(expected_results, 'id')
+        
+        for actual_result, expected_result in zip(actual_results, expected_results):
+            self.assertEqual(actual_result['id'], expected_result['id'])
+            self.assertEqual(actual_result['name'], expected_result['name'])
+            self.assertEqual(actual_result['index'], expected_result['index'])
+            expected_extra = expected_result.get('extra', 'dummy')
+            self.assertEqual(actual_result['extra'], expected_extra)
+                
+    def test_set_up(self):
+        response = test_get_rest_model_data('rest-compound-key')
+        self.assertEqual(response.status_code, 200)
+        actual_results = simplejson.loads(response.content)
+        self.check_query_results(actual_results, self.TEST_DATA)
+        
+    def test_delete_by_id(self):
+        test_delete_rest_model_data('rest-compound-key', {'id': 'foo|3'})
+        test_delete_rest_model_data('rest-compound-key', {'id': 'bar|4'})
+        response = test_get_rest_model_data('rest-compound-key')
+        self.assertEqual(response.status_code, 200)
+        actual_results = simplejson.loads(response.content)
+        self.check_query_results(actual_results, self.TEST_DATA[1:-1])
+    
+    def test_delete_by_fields(self):
+        test_delete_rest_model_data('rest-compound-key', {'name': 'bar', 'index': 4})
+        response = test_get_rest_model_data('rest-compound-key')
+        self.assertEqual(response.status_code, 200)
+        actual_results = simplejson.loads(response.content)
+        self.check_query_results(actual_results, self.TEST_DATA[:-1])
+        
+class UserDataTest(TestCase):
+    
+    TEST_DATA = [
+        # name, data, binary, content-type
+        ('test/foobar', 'hello world\nanother line', False, None),
+        ('test/json-test', '[0,1,2]', False, 'application/json'),
+        ('test/binary-test', '\x01\x02\x03\x04\x55', True, None),
+    ]
+    
+    MORE_TEST_DATA = [
+        ('moretests/foo1', 'moretest1', False, None),
+        ('moretests/foo2', 'moretest2', False, None),
+    ]
+    
+    def add_user_data(self, client, user_data):
+        for name, data, binary, content_type in user_data:
+            if not content_type:
+                if binary:
+                    content_type = 'application/octet-stream'
+                else:
+                    content_type = 'text/plain'
+            url = test_construct_rest_url('data/' + name, {'binary':binary})
+            response = client.put(url, data, content_type)
+            self.assertEquals(response.status_code, 200)
+
+    def check_expected_info_list(self, info_list, expected_info_list):
+        self.assertEqual(type(info_list), list)
+        info_list = get_sorted_list(info_list, 'name', True)
+        expected_info_list = get_sorted_list(expected_info_list, None, True)
+        self.assertEqual(len(info_list), len(expected_info_list))
+        for i in range(len(info_list)):
+            data = info_list[i]
+            expected_data = expected_info_list[i]
+            expected_name = expected_data[0]
+            expected_url_path = 'rest/v1/data/' + expected_name + '/'
+            self.assertEqual(data['name'], expected_name)
+            self.assertEqual(data['url_path'], expected_url_path)
+
+    def get_info_list(self, client, query_params=None):
+        url = test_construct_rest_url('data', query_params)
+        get_response = client.get(url)
+        self.assertEqual(get_response.status_code, 200)
+        info_list = simplejson.loads(get_response.content)
+        
+        # The view for listing user data items hard-codes inclusion of some
+        # *magic* user data items corresponding to the startup-config
+        # and update-config, depending on the presence of certain files
+        # in the file system. To make the unit tests work correctly if/when
+        # either/both of those items are added we do this filtering pass
+        # over the items returned from the REST API. Ugly hack!
+        info_list = [item for item in info_list if '-config' not in item['name']]
+        
+        return info_list
+
+    def test_user_data_basic(self):
+        c = Client()
+        self.add_user_data(c, self.TEST_DATA)
+        for name, data, binary, content_type in self.TEST_DATA:
+            if not content_type:
+                if binary:
+                    content_type = 'application/octet-stream'
+                else:
+                    content_type = 'text/plain'
+            url = test_construct_rest_url('data/' + name)
+            get_response = c.get(url)
+            self.assertEqual(get_response.content, data)
+            self.assertEqual(get_response['Content-Type'], content_type)
+
+    def test_user_data_delete(self):
+        c = Client()
+        
+        self.add_user_data(c, self.TEST_DATA)
+        self.add_user_data(c, self.MORE_TEST_DATA)
+        
+        # Do a delete with a query filter
+        url = test_construct_rest_url('data', {'name__startswith':'moretests/'})
+        response = c.delete(url)
+        self.assertEqual(response.status_code, 200)
+        
+        info_list = self.get_info_list(c)
+        expected_info_list = self.TEST_DATA
+        self.check_expected_info_list(info_list, expected_info_list)
+        
+        # Do a delete of a specific user data element
+        url = test_construct_rest_url('data/' + self.TEST_DATA[0][0])
+        response = c.delete(url)
+        self.assertEqual(response.status_code, 200)
+
+        info_list = self.get_info_list(c)
+        expected_info_list = self.TEST_DATA[1:]
+        self.check_expected_info_list(info_list, expected_info_list)
+
+    def test_user_data_info(self):
+
+        c = Client()
+        
+        self.add_user_data(c, self.TEST_DATA)
+        self.add_user_data(c, self.MORE_TEST_DATA)
+        
+        info_list = self.get_info_list(c)
+        expected_info_list = self.TEST_DATA + self.MORE_TEST_DATA
+        self.check_expected_info_list(info_list, expected_info_list)
+        
+        info_list = self.get_info_list(c, {'name__startswith':'test/'})
+        expected_info_list = self.TEST_DATA
+        self.check_expected_info_list(info_list, expected_info_list)
diff --git a/sdncon/rest/validators.py b/sdncon/rest/validators.py
new file mode 100755
index 0000000..856038a
--- /dev/null
+++ b/sdncon/rest/validators.py
@@ -0,0 +1,448 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+import re
+import os.path
+
+from django.forms import ValidationError
+from django.core.validators import RegexValidator, MinValueValidator, MaxValueValidator
+
+validate_mac_address = RegexValidator('^(([A-Fa-f\d]){2}:?){5}[A-Fa-f\d]{2}$', 'MAC address is a 48-bit quantity, expressed in hex as AA:BB:CC:DD:EE:FF', 'invalid')
+validate_dpid = RegexValidator('^([A-Fa-f\d]{2}:?){7}[A-Fa-f\d]{2}$', 'Switch DPID is a 64-bit quantity, expressed in hex as AA:BB:CC:DD:EE:FF:00:11', 'invalid')
+validate_controller_id = RegexValidator('^[A-Fa-f\d]{8}-([A-Fa-f\d]{4}-){3}[A-Fa-f\d]{12}$', 'Controller ID is a 128-bit quantity, expressed in hex as aabbccdd-eeff-0011-2233-445566778899', 'invalid')
+
+class UfwProtocolValditor(object):
+    def __init__(self):
+        pass
+    
+    def __call__(self, value):
+        if not (value != "tcp" or value != "udp" or value != 'vrrp'):
+            raise ValidationError("Protocol must be either 'tcp' or 'udp' or 'vrrp'")
+
+octet = r'(?:0|[1-9][0-9]*)'
+IP_RE = re.compile("^" + octet + '[.]' + octet
+                   + '[.]' + octet + '[.]' + octet + "$")
+
+class IpValidator(object):
+    def __call__(self, value):
+        if not IP_RE.match(value) or len([x for x in value.split('.') if int(x) < 256]) != 4:
+            raise ValidationError("IP must be in dotted decimal format, 234.0.59.1")
+            
+class IpMaskValidator(object):
+    def __call__(self, value):
+        if not IP_RE.match(value):
+            raise ValidationError("IP must be in dotted decimal format, 255.255.128.0")
+        invalid_netmask = False
+        invalid_inverse_netmask = False
+        lookForZero = False
+        for x in value.split('.'):
+            xInt = int(x)
+            if lookForZero:
+                if xInt:
+                    invalid_netmask = True
+                    break  # go check inverse mask
+            if xInt != 255:
+                if xInt:
+                    if xInt >= 128:
+                        while (xInt % 2) == 0:
+                            xInt = xInt >> 1
+                        if xInt & (xInt + 1) == 0:
+                            continue
+                    invalid_netmask = True
+                    break # go check inverse mask
+                lookForZero = True
+
+        lookForOne = False
+        for x in value.split('.'):
+            xInt = int(x)
+            if lookForOne: # all bits should be 1 bits
+                if (xInt != 255):
+                    invalid_inverse_netmask = True
+                    break
+                else:
+                    continue
+            if xInt != 0:
+                # check for contiguous 1-bits from LSb
+                lookForOne = True
+                if xInt == 255:
+                    continue
+                if xInt & (xInt + 1) != 0:
+                    invalid_inverse_netmask = True
+                    break
+        if invalid_netmask and invalid_inverse_netmask: # no valid mask, then raise exception
+            raise ValidationError("Invalid IP Mask, should be like 255.255.128.0 or 0.0.127.255")
+
+
+class PortRangeSpecValidator(object):
+    def __init__(self):
+        self.RANGE_RE = re.compile(r'^([A-Za-z0-9-/\.:]*?)(\d+)\-(\d+)$')
+        self.SINGLE_RE = re.compile(r'^([A-Za-z0-9-/\.:]+)$')
+    def __call__(self, value):
+        values = value.split(',')
+        for v in values:
+            m = self.RANGE_RE.match(v);
+            if (m):
+                startport = int(m.group(2))
+                endport = int(m.group(3))
+                if (startport >= endport):
+                    raise ValidationError("Invalid range numerals: %d-%d" % (startport, endport))
+            elif not self.SINGLE_RE.match(v):
+                raise ValidationError("Must be a list of ports or ranges, such as 'A10-15,B25,C1-13'")
+
+class VLANRangeSpecValidator(object):
+    def __init__(self):
+        self.RANGE_RE = re.compile(r'^([\d]+)\-([\d]+)$')
+        self.SINGLE_RE = re.compile(r'^[\d]+$')
+
+    def __call__(self, value):
+        values = value.split(',')
+        for v in values:
+            m = self.RANGE_RE.match(v);
+            if v == 'untagged':
+                pass
+            elif (m):
+                if (int(m.group(1)) >= int(m.group(2))):
+                    raise ValidationError("Invalid range numerals in {}: {} must be less than {}".format(v, m.group(1), m.group(2)))
+                elif (int(m.group(1)) > 4095):
+                    raise ValidationError("Invalid VLAN: {} must be in range 0-4095".format(m.group(1)))
+                elif (int(m.group(2)) < 0):
+                    raise ValidationError("Invalid VLAN: {} must be in range 0-4095".format(m.group(2)))
+            elif not self.SINGLE_RE.match(v):
+                raise ValidationError("Must be a list of VLANs or ranges,"
+                                      " such as '5-20,45,4053,untagged'")
+            elif int(v) > 4095 or int(v) < 0:
+                raise ValidationError("Invalid VLAN: {} must be in range 0-4095".format(v))
+
+class TagSpecValidator(object):
+    def __init__(self):
+        self.TAG_NAME_RE = re.compile(r'^([a-zA-Z0-9_-]+(?:\.?[a-zA-Z0-9_-]+)*)=+([a-zA-Z0-9_-]+)$')
+
+    def __call__(self,value):
+        values = value.split(',')
+        for v in values:
+            v = v.strip()
+            if not self.TAG_NAME_RE.match(v):
+                raise ValidationError("Invalid tag: " + 
+                        '='.join(v.split('|')) +
+                        "\nFormat: tag namespace.namel value1, " +
+                        "where namespace may be empty or must be a-z, A-Z, 0-9, -, . or _, " + 
+                        "name and value must be a-z, A-Z, 0-9, - or _")
+
+class CidrValidator(object):
+    def __init__(self, mask_required=True):
+        self.mask_required = mask_required
+        self.CIDR_RE = re.compile(r'^(\d{1,3}\.){3}\d{1,3}/\d{1,2}?$')
+
+    def __call__(self, value):
+        ip_validator = IpValidator()
+        if self.CIDR_RE.match(value):
+            ip, mask = value.split('/')
+            ip_validator(ip)
+            if int(mask) < 1 or int(mask) > 32:
+                raise ValidationError("Mask should be between 1-32")
+        else:
+            if self.mask_required: # if mask was required and we didn't match above, problem!
+                raise ValidationError("Must be in dotted decimal format with a mask between 1-32")
+            else:
+                ip_validator(value)
+        
+class EnumerationValidator(object):
+    def __init__(self, enumerated_values, case_sensitive=False, message=None, code=None):
+        self.case_sensitive = case_sensitive
+        if case_sensitive:
+            self.enumerated_values = enumerated_values
+        else:
+            self.enumerated_values = [s.lower() for s in enumerated_values]
+        if not message:
+            message = 'Invalid enumerated value'
+        self.message = message
+        if not code:
+            code = 'invalid'
+        self.code = code
+
+    def __call__(self, value):
+        if not self.case_sensitive:
+            value = value.lower()
+        if value not in self.enumerated_values:
+            raise ValidationError(self.message, self.code)
+
+class ChoicesValidator(EnumerationValidator):
+    def __init__(self, choices, case_sensitive=False, message=None, code=None):
+        enumerated_values = [choice[0] for choice in choices]
+        EnumerationValidator.__init__(self, enumerated_values, case_sensitive, message, code)
+
+class RangeValidator(object):
+    def __init__(self, min, max):
+        self.min_value_validator = MinValueValidator(min)
+        self.max_value_validator = MaxValueValidator(max)
+
+    def __call__(self, value):
+        try:
+            self.min_value_validator(int(value))
+            self.max_value_validator(int(value))
+        except ValidationError:
+            raise ValidationError('Ensure this value is within the range (%d-%d)' %
+                                  (self.min_value_validator.limit_value,
+                                   self.max_value_validator.limit_value))
+
+class ControllerAliaVsalidator(object):
+    def __init__(self):
+        self.CONTROLLER_ALIAS_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+
+    def __call__(self, value):
+        if not self.CONTROLLER_ALIAS_RE.match(value):
+            raise ValidationError("controller alias name must ba a-z, 0-9, _ or _")
+
+class SwitchAliasValidator(object):
+    def __init__(self):
+        self.SWITCH_ALIAS_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+
+    def __call__(self, value):
+        if not self.SWITCH_ALIAS_RE.match(value):
+            raise ValidationError("switch alias name must ba a-z, 0-9, _ or _")
+
+class PortAliasValidator(object):
+    def __init__(self):
+        self.PORT_ALIAS_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+
+    def __call__(self, value):
+        if not self.PORT_ALIAS_RE.match(value):
+            raise ValidationError("port alias name must ba a-z, 0-9, _ or _")
+
+class HostAliasValidator(object):
+    def __init__(self):
+        self.HOST_ALIAS_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+
+    def __call__(self, value):
+        if not self.HOST_ALIAS_RE.match(value):
+            raise ValidationError("host alias name must ba a-z, 0-9, _ or _")
+
+class AddressSpaceNameValidator(object):
+    def __init__(self):
+        self.ADDRESS_SPACE_NAME_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+
+    def __call__(self,value):
+        if not self.ADDRESS_SPACE_NAME_RE.match(value):
+            raise ValidationError("address-space name must be a-z, A-Z, 0-9, - or _")
+
+class TenantNameValidator(object):
+    def __init__(self):
+        self.TENANT_NAME_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+
+    def __call__(self,value):
+        if not self.TENANT_NAME_RE.match(value):
+            raise ValidationError("tenant name must be a-z, A-Z, 0-9, - or _")
+
+class GeneralNameValidator(object):
+    def __init__(self):
+        self.GENERAL_NAME_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+
+    def __call__(self,value):
+        if not self.GENERAL_NAME_RE.match(value):
+            raise ValidationError("Name must be a-z, A-Z, 0-9, - or _")
+
+class VnsNameValidator(object):
+    def __init__(self):
+        self.VNS_NAME_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+
+    def __call__(self,value):
+        if not self.VNS_NAME_RE.match(value):
+            raise ValidationError("vns name must be a-z, A-Z, 0-9, - or _")
+
+class VnsInterfaceNameValidator(object):
+    def __init__(self):
+        self.VNS_INTERFACE_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+        self.PORT_RE = re.compile(r'^([A-Za-z0-9-]*?)(\d+)$')
+        self.MAC_RE = re.compile(r'^(([A-Fa-f\d]){2}:?){5}[A-Fa-f\d]{2}$')
+
+    def __call__(self,value):
+        if not self.VNS_INTERFACE_RE.match(value):
+            items = value.split('/')
+            if len(items) == 2:
+                if not self.PORT_RE.match(items[1]) and \
+                    not self.MAC_RE.match(items[1]):
+                        raise ValidationError("interface name after '/' must be either a port or a mac address")
+            else:
+                raise ValidationError("invalid syntax for interface name")
+
+class VnsAclNameValidator(object):
+    def __init__(self):
+        self.VNS_ACL_NAME_RE = re.compile(r'[a-zA-Z0-9_-]+$')
+
+    def __call__(self,value):
+        if not self.VNS_ACL_NAME_RE.match(value):
+            raise ValidationError("acl name must be a-z, A-Z, 0-9, - or _")
+
+class VnsAclEntryActionValidator(object):
+    def __call__(self,value):
+        if not "permit".startswith(value.lower()) and \
+           not "deny".startswith(value.lower()):
+            raise ValidationError("acl entry action must be 'permit' or 'deny'")
+
+class VnsInterfaceAclInOutValidator(object):
+    def __call__(self,value):
+        if not "in".startswith(value.lower()) and \
+           not "out".startswith(value.lower()):
+            raise ValidationError("acl entry action must be 'permit' or 'deny'")
+
+class VnsRuleNameValidator(object):
+    def __init__(self):
+        self.IF_NAME_RE = re.compile(r'^\d*$')
+
+    def __call__(self, value):
+        if not self.IF_NAME_RE.match(value):
+            print value
+            raise ValidationError("Invalid rule name, only digits allowed")
+
+class TagNameValidator(object):
+    def __init__(self):
+        self.TAG_NAME_RE = re.compile(r'^[a-zA-Z0-9_-]+(?:\.?[a-zA-Z0-9_-]+)*(?:\|[a-zA-Z0-9_-]+)+$')
+
+    def __call__(self,value):
+        if not self.TAG_NAME_RE.match(value):
+            raise ValidationError("Invalid tag: " + value + "\nFormat: tag namespace|namel|value1, " +
+                        "where namespace may be empty or must be a-z, A-Z, 0-9, -, . or _, " + 
+                        "name and value must be a-z, A-Z, 0-9, - or _")
+
+
+class VnsArpModeValidator(object):
+    def __init__(self):
+        self.ARP_MODES = ['flood-if-unknown', 'always-flood', 'drop-if-unknown']
+
+    def __call__(self,value):
+        if not value in self.ARP_MODES:
+            raise ValidationError("must be one of %s" % ', '.join(self.ARP_MODES))
+
+class VnsDhcpModeValidator(object):
+    def __init__(self):
+        self.DHCP_MODES = ['flood-if-unknown', 'always-flood', 'static']
+
+    def __call__(self,value):
+        if not value in self.DHCP_MODES:
+            raise ValidationError("must be one of %s" % ', '.join(self.DHCP_MODES))
+
+class VnsBroadcastModeValidator(object):
+    def __init__(self):
+        self.BROADCAST_MODES = ['drop', 'always-flood', 'forward-to-known']
+
+    def __call__(self,value):
+        if not value in self.BROADCAST_MODES:
+            raise ValidationError("must be one of %s" % ', '.join(self.BROADCAST_MODES))
+        
+class IntfNameValidator(object):
+    def __init__(self):
+        self.IntfName_RE = re.compile(r'^ethernet[0-9]')
+        
+    def __call__(self, value):
+        if not self.IntfName_RE.match(value):
+            raise ValidationError("Interface name must be Ethernet<num>")
+
+class DomainNameValidator(object):
+    def __init__(self):
+        self.DomainName_RE = re.compile(r'^([a-zA-Z0-9-]+.?)+$')
+    def __call__(self,value):
+        if not self.DomainName_RE.match(value):
+            raise ValidationError("Value must be a valid domain name")
+
+class IpOrDomainNameValidator(object):
+    def __init__(self):
+        self.DomainName_RE = re.compile(r'^([a-zA-Z0-9-]+.?)+$')
+        
+    def __call__(self,value):
+        if not IP_RE.match(value) and not self.DomainName_RE.match(value):
+            raise ValidationError("Value must be a valid IP address or domain name")
+        
+class TimeZoneValidator(object):
+    timezones = None
+    def __call__(self, value):
+        if not TimeZoneValidator.timezones:
+            import pytz
+            TimeZoneValidator.timezones = pytz.all_timezones
+        if value not in TimeZoneValidator.timezones:
+            raise ValidationError("Invalid time zone string")
+        
+class VCenterMgrIdsValidator(object):
+    def __init__(self):
+        self.VCenterMgrId_RE = re.compile(r'^[a-zA-Z]([a-zA-Z0-9_-])*')
+    def __call__(self,value):
+        if not self.VCenterMgrId_RE.match(value):
+            raise ValidationError("Value must be a valid name, starts with a alphabet and can have alphabets, numbers, _ and -")
+        
+class VCenterObjNamesValidator(object):
+    def __init__(self):
+        self.VCenterObjName_RE = re.compile(r'(?!.*\|.*)')
+    def __call__(self, value):
+        if not self.VCenterObjName_RE.match(value):
+            raise ValidationError("VCenter object names can contain any character except '|'")        
+    
+class FeatureValidator(object):
+    """Validates that a specific feature has been installed
+
+    We assume that a feature has been installed if the following file exists:
+        {sdncon.SDN_ROOT}/feature/<feature-name>
+
+    NOTE: The feature is enabled/disabled for use by updating the controller
+    object, this validator just ensures that before we enable a feature, it
+    has been actually installed.
+    """
+    def __init__(self, feature, featuredir=None):
+        self.feature = feature
+        if featuredir is None:
+            featuredir = \
+                    os.path.join(os.path.sep, 'opt', 'sdnplatform', 'feature')
+        self.featurefile = os.path.join(featuredir, feature)
+
+    def __call__(self, value):
+        if value and not os.path.isfile(self.featurefile):
+            raise ValidationError(
+                    'Feature not installed, please install "%s"' %
+                    self.feature)
+
+class VlanStringValidator(object):
+    def __call__(self, value):
+        self.vlan = 0
+        try:
+            self.vlan = int(value)
+            if (self.vlan < 1 or self.vlan > 4095):
+                raise ValidationError("VLAN must be in the range of 1 to 4095 with 4095 as untagged")
+        except ValueError:
+            raise ValidationError(
+             "VLAN must be in the range of 1 to 4095 with 4095 as untagged")
+
+
+class SafeForPrimaryKeyValidator(object):
+    """Validates that a string does not contain any character that would be 
+    illegal for use in a primary key. Currently this is the pipe | symbol
+    """
+
+    def __call__(self, value):
+        if "|" in value:
+            raise ValidationError(
+             "The pipe symbol '|' is not a valid character")
+        
+
+class IsRegexValidator(object):
+    """Validates that a given string is a valid regular expression
+    """
+
+    def __call__(self, value):
+        try:
+            value = str(value)
+            re.compile(value)
+        except re.error as e:
+            raise ValidationError(
+              "Input is not a valid regular expression: %s", e)
+
diff --git a/sdncon/rest/views.py b/sdncon/rest/views.py
new file mode 100755
index 0000000..66dc75a
--- /dev/null
+++ b/sdncon/rest/views.py
@@ -0,0 +1,2208 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.db.models import AutoField, BooleanField, IntegerField, FloatField, ForeignKey
+from django.forms import ValidationError
+from django.http import HttpResponse
+from django.utils import simplejson
+from functools import wraps
+#from sdncon.controller.models import Controller
+#from sdncon.controller.models import ControllerAlias, ControllerDomainNameServer, ControllerInterface, FirewallRule
+#from sdncon.controller.models import Switch, Port, PortAlias, Link
+from sdncon.rest.models import UserData
+from sdncon.controller.notification import begin_batch_notification, end_batch_notification
+from django.views.decorators.csrf import csrf_exempt
+import base64
+import urllib
+import urllib2
+import sys
+import json
+import os
+import re
+import time
+import traceback
+import collections
+import uuid
+import subprocess
+from datetime import datetime
+from sdncon.controller.oswrapper import exec_os_wrapper
+from sdncon.controller.config import get_local_controller_id
+from sdncon.rest.config import config_check_state
+from sdncon.controller.oswrapper import get_system_version_string
+import sdncon
+
+TEXT_PLAIN_CONTENT_TYPE = 'text/plain'
+TEXT_JAVASCRIPT_CONTENT_TYPE = 'text/javascript'
+JSON_CONTENT_TYPE = 'application/json'
+BINARY_DATA_CONTENT_TYPE = 'application/octet-stream'
+
+onos = 1
+
+if onos == 1:
+    #CONTROLLER_URL_PREFIX = 'http://localhost:9000/wm/'
+    CONTROLLER_URL_PREFIX = 'http://localhost:8080/wm/'
+else:
+    CONTROLLER_URL_PREFIX = 'http://localhost:8080/wm/'
+
+def controller_url(*elements):
+    return CONTROLLER_URL_PREFIX + '/'.join(elements)
+
+class RestException(Exception):
+    pass
+        
+class RestInvalidDataTypeException(RestException):
+    def __init__(self, name):
+        super(RestInvalidDataTypeException,self).__init__('Invalid data type: ' + name)
+
+class RestInvalidMethodException(RestException):
+    def __init__(self):
+        super(RestInvalidMethodException,self).__init__('Invalid HTTP method')
+
+class RestResourceNotFoundException(RestException):
+    def __init__(self, url):
+        super(RestResourceNotFoundException,self).__init__('Resource not found: ' + url)
+
+class RestDatabaseConnectionException(RestException):
+    def __init__(self):
+        super(RestDatabaseConnectionException,self).__init__('Error connecting to database')
+        
+class RestAuthenticationRequiredException(RestException):
+    def __init__(self):
+        super(RestAuthenticationRequiredException,self).__init__('Authentication required')
+
+class RestInvalidQueryParameterException(RestException):
+    def __init__(self, param_name):
+        super(RestInvalidQueryParameterException, self).__init__('Invalid query parameter: ' + str(param_name))
+
+class RestInvalidFilterParameterException(RestException):
+    def __init__(self, param_name):
+        super(RestInvalidFilterParameterException, self).__init__('Filter query parameters not allowed when URL contains resource iD: ' + str(param_name))
+
+class RestNoListResultException(RestException):
+    def __init__(self):
+        super(RestNoListResultException, self).__init__('The query result must be a single instance if the "nolist" query param is set')
+
+class RestInvalidPutDataException(RestException):
+    def __init__(self):
+        super(RestInvalidPutDataException, self).__init__('The request data for a PUT request must be a JSON dictionary object')
+
+class RestMissingRequiredQueryParamException(RestException):
+    def __init__(self, param_name):
+        super(RestMissingRequiredQueryParamException, self).__init__('Missing required query parameter: ' + str(param_name))
+
+class RestValidationException(RestException):
+    def __init__(self, model_error=None, field_errors=None):
+        # Build the exception message from model error and field errors
+        message = 'Validation error'
+        if model_error:
+            message = message + '; ' + model_error
+        if field_errors:
+            message += '; invalid fields: {'
+            first_time = True
+            for field_name, field_message in field_errors.items():
+                if not first_time:
+                    message += '; '
+                else:
+                    first_time = False
+                message = message + field_name + ': ' + field_message
+                
+            message += '}'
+            
+        super(RestValidationException, self).__init__(message)
+        self.model_error = model_error
+        self.field_errors = field_errors
+        
+class RestModelException(RestException):
+    def __init__(self, exc):
+        super(RestModelException, self).__init__('Error: ' + str(exc))
+
+class RestSaveException(RestException):
+    def __init__(self, exc):
+        super(RestSaveException, self).__init__('Error saving data: ' + str(exc))
+
+class RestInvalidOrderByException(RestException):
+    def __init__(self,field_name):
+        super(RestInvalidOrderByException, self).__init__('Invalid orderby field: ' + field_name)
+        
+class RestInternalException(RestException):
+    def __init__(self, exc):
+        super(RestInternalException,self).__init__('Unknown REST error: ' + unicode(exc))
+
+class RestUpgradeException(RestException):
+    def __init__(self, exc):
+        super(RestUpgradeException, self).__init__('Error: ' + str(exc))
+
+class RestProvisionException(RestException):
+    def __init__(self, exc):
+        super(RestProvisionException, self).__init__('Error: ' + str(exc))
+
+class RestDecommissionException(RestException):
+    def __init__(self, exc):
+        super(RestDecommissionException, self).__init__('Error: ' + str(exc))
+
+class RestInvalidLog(RestException):
+    def __init__(self, exc):
+        super(RestInvalidLog, self).__init__('Error: ' + str(exc))
+
+def handle_validation_error(model_info, validation_error):
+    model_error = None
+    field_errors = None
+    if hasattr(validation_error, 'message_dict'):
+        # The field errors we get in the ValidationError are a bit different
+        # then what we want for the RestValidationException. First, we
+        # need to convert the Django field name to the (possibly renamed)
+        # REST field name. Second, the per-field error message is possibly a
+        # list of messages, which we concatenate into a single string for the
+        # RestValidationException
+        for field_name, field_message in validation_error.message_dict.items():
+            if type(field_message) in (list, tuple):
+                converted_field_message = ''
+                for msg in field_message:
+                    converted_field_message = converted_field_message + msg + ' '
+            else:
+                converted_field_message += unicode(field_message)
+            if field_name == '__all__':
+                model_error = converted_field_message
+            else:
+                if not field_errors:
+                    field_errors = {}
+                field_info = model_info.field_name_dict.get(field_name)
+                if field_info:
+                    field_errors[field_info.rest_name] = converted_field_message
+                else:
+                    field_errors[field_name] = 'Private field invalid; ' + converted_field_message
+    elif hasattr(validation_error, 'messages'):
+        model_error = ':'.join(validation_error.messages)
+    else:
+        model_error = str(validation_error)
+    raise RestValidationException(model_error, field_errors)
+
+def get_successful_response(description=None, status_code=200):
+    content = get_successful_response_data(description)
+    return HttpResponse(content, JSON_CONTENT_TYPE, status_code)
+
+def get_successful_response_data(description = 'success'):
+    obj = {'description': description}
+    return simplejson.dumps(obj)
+ 
+def get_sdnplatform_response(url, timeout = None):
+    
+    try:
+        response_text = urllib2.urlopen(url, timeout=timeout).read()
+        return HttpResponse(response_text, JSON_CONTENT_TYPE)
+    except urllib2.HTTPError, e:
+        response_text = e.read()
+        response = simplejson.loads(response_text)
+        response['error_type'] = "SDNPlatformError"
+        return HttpResponse(content=simplejson.dumps(response), 
+                            status=e.code, 
+                            content_type=JSON_CONTENT_TYPE)
+
+def get_sdnplatform_query(request, path):
+    """
+    This returns controller-level storage table list
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    url = controller_url(path) + '/?%s' % request.META['QUERY_STRING']
+    return get_sdnplatform_response(url)        
+
+def safe_rest_view(func):
+    """
+    This is a decorator that takes care of exception handling for the
+    REST views so that we return an appropriate error HttpResponse if
+    an exception is thrown from the view
+    """
+    @wraps(func)
+    def _func(*args, **kwargs):
+        try:
+            response = func(*args, **kwargs)
+        except Exception, exc:
+            end_batch_notification(True)
+            if not isinstance(exc, RestException):
+                # traceback.print_exc()
+                exc = RestInternalException(exc)
+            response_obj = {'error_type': exc.__class__.__name__, 'description': unicode(exc)}
+            if isinstance(exc, RestValidationException):
+                if exc.model_error:
+                    response_obj['model_error'] = exc.model_error
+                if exc.field_errors:
+                    response_obj['field_errors'] = exc.field_errors
+            content = simplejson.dumps(response_obj)
+            content_type = JSON_CONTENT_TYPE
+            
+            if isinstance(exc, RestInvalidMethodException):
+                status_code = 405
+            elif isinstance(exc, RestResourceNotFoundException):
+                status_code = 404
+            elif isinstance(exc, RestInternalException):
+                status_code = 500
+            else:
+                status_code = 400
+            response = HttpResponse(content, content_type, status_code)
+            if isinstance(exc, RestInvalidMethodException):
+                response['Allow'] = "GET, PUT, DELETE"
+        return response
+    return _func
+
+rest_model_info_dict = {}
+
+class RestFieldInfo(object):
+    def __init__(self, name, django_field_info, hidden=False,
+                 rest_name=None, json_serialize=False):
+        self.name = name
+        self.django_field_info = django_field_info
+        self.rest_name = rest_name
+        self.json_serialize = json_serialize
+        
+class RestModelInfo(object):
+    def __init__(self, rest_name, model_class):
+        self.rest_name = rest_name
+        self.model_class = model_class
+        self.primary_key = None
+        self.field_name_dict = {}
+        self.rest_name_dict = {}
+        
+        for field in model_class._meta.local_fields:
+            field_name = field.name
+            rest_name = field.name
+            if field.primary_key:
+                self.primary_key = field_name
+            # TODO: Are there other field types that should be included here?
+            json_serialize =  type(field) not in (AutoField, BooleanField, IntegerField, FloatField)
+            self.set_field_info(field_name, rest_name, field, json_serialize)
+
+    
+    # this is how a RestFieldInfo is created - pass in django_field_info
+    def get_field_info(self, field_name, django_field_info=None):
+        field_info = self.field_name_dict.get(field_name)
+        if not field_info and django_field_info:
+            field_info = RestFieldInfo(field_name, django_field_info)
+            self.field_name_dict[field_name] = field_info
+        return field_info
+    
+    def hide_field(self, field_name):
+        field_info = self.get_field_info(field_name)
+        del self.field_name_dict[field_name]
+        del self.rest_name_dict[field_info.rest_name]
+        
+    def set_field_info(self, field_name, rest_name, django_field_info, json_serialize=None):
+        field_info = self.get_field_info(field_name, django_field_info)
+        if field_info.rest_name in self.rest_name_dict:
+            del self.rest_name_dict[field_info.rest_name]
+        field_info.rest_name = rest_name
+        if json_serialize != None:
+            field_info.json_serialize = json_serialize
+        self.rest_name_dict[rest_name] = field_info
+
+def get_rest_model_info(name):
+    return rest_model_info_dict[name]
+
+def add_rest_model_info(info):
+    if rest_model_info_dict.get(info.rest_name):
+        raise RestException('REST model info already exists')
+    rest_model_info_dict[info.rest_name] = info
+    
+rest_initialized = False
+
+def get_default_rest_name(model):
+    # TODO: Ideally should do something a bit smarter here.
+    # Something like convert from camel-case class names to hyphenated names:
+    # For example:
+    #  MyTestClass => my-test-class
+    #  MyURLClass => my-url-class
+    #
+    # This isn't super-important for now, since you can set it explicitly
+    # with the nested Rest class.
+    return model.__name__.lower()
+
+def initialize_rest():
+    global rest_initialized
+    if rest_initialized:
+        return
+    
+    from django.db.models import get_models
+    for model in get_models():
+                
+        # If the model class has a nested class named 'Rest' then that means
+        # the model should be exposed in the REST API.
+        if hasattr(model, 'Rest'):
+            # By default the REST API uses the lower-case-converted name
+            # of the model class as the name in the REST URL, but this can
+            # be overridden by defining the 'NAME' attribute in the Rest class.
+            if hasattr(model.Rest, 'NAME'):
+                rest_name = model.Rest.NAME
+            else:
+                rest_name = get_default_rest_name(model)
+
+            if model._meta.proxy:
+                # This is a proxy class, drop through to the real one
+                base_model = model._meta.proxy_for_model
+            else:
+                base_model = model
+            
+            # OK, we have the basic REST info, so we can create the info class
+            rest_model_info = RestModelInfo(rest_name, base_model)
+            
+            # Check if there are any private or renamed fields
+            if hasattr(model.Rest, 'FIELD_INFO'):
+                for field_info in model.Rest.FIELD_INFO:
+                    field_name = field_info['name']
+                    rest_field_info = rest_model_info.get_field_info(field_name)
+                    # Check if field exists in models - don't allow field only here in FIELD_INFO)
+                    if not rest_field_info:
+                        # LOOK! This field only exists in FIELD_INFO - skip
+                        print "ERROR: %s for %s only in FIELD_INFO" % (field_name, rest_name)
+                        continue
+                    
+                    if field_info.get('private', False):
+                        rest_model_info.hide_field(field_name)
+                    else:
+                        rest_name = field_info.get('rest_name')
+                        if rest_name:
+                            rest_model_info.set_field_info(field_name, rest_name, rest_field_info.django_field_info)
+            
+            # Finished setting it up, so now add it to the list
+            add_rest_model_info(rest_model_info)
+    
+    rest_initialized = True
+
+initialize_rest()
+
+@safe_rest_view
+def do_model_list(request):
+    """
+    This returns the list of models available in the REST API.
+    """
+    
+    json_model_list = []
+    for model_name in rest_model_info_dict.keys():
+        json_model_info = {}
+        json_model_info["name"] = model_name
+        json_model_info["url_path"] = "rest/v1/model/" + model_name + "/"
+        json_model_list.append(json_model_info)
+
+    json_data = simplejson.dumps(json_model_list)
+    return HttpResponse(json_data, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_realtimestats(request, stattype, dpid):
+    """
+    This returns realtime statistics (flows, ports, table, aggregate,
+    desc, ...)  for a dpid by calling the localhost sdnplatform
+    """
+    #raise RestInvalidMethodException()
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    #url = controller_url('core', 'switch', dpid, stattype, 'json')
+    if stattype == 'group':
+        stattype = 'groupStats'
+    if stattype == 'groupdesc':
+        stattype = 'groupDesc'
+    url = "http://localhost:8080/wm/floodlight/core/switch/%s/%s/json" % (dpid, stattype)
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_realtimegroupstats(request, groupId, dpid ):
+    """
+    This returns realtime group statistics for specified groupId
+    for a dpid by calling the localhost sdnplatform
+    """
+    #raise RestInvalidMethodException()
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    #url = controller_url('core', 'switch', dpid, stattype, 'json')
+    #import error
+    #raise error.ArgumentValidationError('\n\n\n %s' % (groupId))
+    url = "http://localhost:8080/wm/floodlight/core/switch/%s/groupStats/%s/json" % (dpid, groupId)
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_tablerealtimestats(request, tabletype, dpid):
+    """
+    This returns realtime statistics per table (flows (only)
+    current implementation)  for a dpid by calling the localhost sdnplatform
+    """
+    #raise RestInvalidMethodException()
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    #url = controller_url('core', 'switch', dpid, stattype, 'json')
+    url = "http://localhost:8080/wm/floodlight/core/switch/%s/table/%s/flow/json" % (dpid,tabletype)
+    #url ="http://localhost:8080/wm/floodlight/core/switch/00:00:00:00:00:00:00:01/flow/json"
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_sdnplatform_realtimestats(request, stattype, dpid=None, portid=None):
+    """
+    This returns realtime statistics from sdnplatform
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    if dpid == None:
+        url = controller_url('core', 'counter', stattype, 'json')
+    elif portid == None:
+        url = controller_url('core', 'counter', dpid, stattype, 'json')
+    else:
+        url = controller_url('core', 'counter', dpid, portid, stattype, 'json')
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_topology_tunnel_verify(request, srcdpid=None, dstdpid=None):
+    """
+    This initiates a liveness detection of tunnels.
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    urlstring = srcdpid + '/' + dstdpid
+    url = controller_url('topology/tunnelverify', urlstring, 'json')
+
+    response_text = urllib2.urlopen(url).read()
+    time.sleep(4)
+    return do_topology_tunnel_status(request, srcdpid, dstdpid)
+
+@safe_rest_view
+def do_topology_tunnel_status(request, srcdpid='all', dstdpid='all'):
+    """
+    This returns the list of tunnels that have failed over the last observation interval.
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    urlstring = srcdpid + '/' + dstdpid
+    url = controller_url('topology/tunnelstatus', urlstring, 'json')
+    response_text = urllib2.urlopen(url).read()
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_sdnplatform_realtimestatus(request, category=None, subcategory=None, srcdpid=None, dstdpid = None):
+    """
+    This returns realtime status of sdnplatform
+    """
+
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    response_text = None
+    url = None
+    if category == 'network':
+        if subcategory == 'cluster':
+            url = controller_url('topology', 'switchclusters', 'json')
+        if subcategory == 'externalports':
+            url = controller_url('topology', 'externalports', 'json')
+        if subcategory == 'tunnelverify':
+            urlstring = subcategory+ '/' + srcdpid + '/' + dstdpid
+            url = controller_url('topology', urlstring, 'json')
+        if subcategory == 'tunnelstatus':
+            url = controller_url('topology', 'tunnelstatus', 'json')
+
+    if url:
+        response_text = urllib2.urlopen(url).read()
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_sdnplatform_realtimetest(http_request, category=None, subcategory=None):
+    """
+    This does a realtime test by sending an "explain packet" as packet in 
+    and collecting the operations performed on the packet
+    """
+
+    if http_request.method != 'PUT':
+        raise RestInvalidMethodException()
+
+    response_text = None
+    url = None
+    if category == 'network':
+        if subcategory == 'explain-packet':
+            # set up the sdnplatform URL for explain packet (at internal port 8080
+            url = controller_url('vns', 'explain-packet', 'json')
+            post_data = http_request.raw_post_data
+            request = urllib2.Request(url, post_data)
+            request.add_header('Content-Type', 'application/json')
+            response = urllib2.urlopen(request)
+            response_text = response.read()
+        elif subcategory == 'path':
+            post_data = json.loads(http_request.raw_post_data)
+            url = controller_url('topology', 'route',
+                                 post_data['src-switch'],
+                                 str(post_data['src-switch-port']),
+                                 post_data['dst-switch'],
+                                 str(post_data['dst-switch-port']),
+                                 'json')
+
+            return get_sdnplatform_response(url)
+
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_sdnplatform_performance_monitor(http_request, category=None,
+                    subcategory=None, type='all'):
+    """
+    This API returns performance related information from the sdnplatform and
+    sdnplatform components
+    """
+
+    if http_request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    response_text = None
+    url = None
+    if category == 'performance-monitor':
+        # set up the sdnplatform URL for explain packet (at internal port 8080
+        url = controller_url('performance', type, 'json')
+        request = urllib2.Request(url)
+        response = urllib2.urlopen(request)
+        response_text = response.read()
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_sdnplatform_internal_debugs(http_request, category=None, subcategory=None,
+                              query='all', component='device-manager'):
+    """
+    This API returns debugging related information from the sdnplatform and
+    sdnplatform components
+    """
+
+    if http_request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    response_text = None
+    url = None
+    if category == 'internal-debugs':
+        # set up the sdnplatform URL for explain packet (at internal port 8080
+        url = controller_url('vns', 'internal-debugs', component, query, 'json')
+        request = urllib2.Request(url)
+        response = urllib2.urlopen(request)
+        response_text = response.read()
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_sdnplatform_event_history(http_request, category=None, subcategory=None,
+                              evHistName='all', count='100'):
+    """
+    This API returns real-time event-history information from the sdnplatform and
+    sdnplatform components
+    """
+
+    if http_request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    response_text = None
+    url = None
+    if category == 'event-history':
+        # set up the sdnplatform URL for explain packet (at internal port 8080
+        url = controller_url('core', 'event-history', evHistName, count, 'json')
+        request  = urllib2.Request(url)
+        response = urllib2.urlopen(request)
+        response_text = response.read()
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_flow_cache(http_request, category=None, subcategory=None,
+                          applName='None', applInstName='all', queryType='all'):
+    """
+    This API returns real-time event-history information from the sdnplatform and
+    sdnplatform components
+    """
+
+    if http_request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    response_text = None
+    url = None
+    if category == 'flow-cache':
+        # set up the sdnplatform URL for explain packet (at internal port 8080
+        url = controller_url('vns', 'flow-cache', applName, applInstName, queryType, 'json')
+        request  = urllib2.Request(url)
+        response = urllib2.urlopen(request)
+        response_text = response.read()
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+
+@safe_rest_view
+def do_vns_realtimestats_flow(http_request, category=None, vnsName="all"):
+    """
+    This gets realtime flows for one or more vnses
+    """
+
+    if http_request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    # set up the sdnplatform URL for per-vns flow (at internal port 8080
+    url = controller_url('vns', 'flow', vnsName, 'json')
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_sdnplatform_counter_categories(request, stattype, layer, dpid=None, portid=None):
+    """
+    This returns counter categories from sdnplatform
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    if dpid == None:
+        url = controller_url('core', 'counter', 'categories', stattype, layer, 'json')
+    elif portid == None:
+        url = controller_url('core', 'counter', 'categories', dpid, stattype, layer, 'json')
+    else:
+        url = controller_url('core', 'counter', 'categories', dpid, portid, stattype, layer, 'json')
+
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+@csrf_exempt
+def do_packettrace(request):
+    """
+    This sets a packet trace in sdnplatform.
+    period: 
+        . >0 starts a trace session with the period
+        . =0 starts a trace session with no timeout
+        . <0 ends an ongoing session
+
+    The request method has to be POST since each request gets an unique sessionID
+    """
+    SESSIONID = 'sessionId'
+    sessionId = ""
+    filter = ""
+    if request.method != 'POST':
+        raise RestInvalidMethodException()
+
+    url = 'http://localhost:8080/wm/vns/packettrace/json'
+    request = urllib2.Request(url, request.raw_post_data, {'Content-Type':'application/json'})
+    try:
+        response = urllib2.urlopen(request)
+        response_text = response.read()
+    except Exception, e:
+        # SDNPlatform may not be running, but we don't want that to be a fatal
+        # error, so we just ignore the exception in that case.
+        pass
+
+    #response_data = json.loads(response_text) 
+    #if SESSIONID in response_data:
+    #    sessionId = response_data[SESSIONID]
+    #response_text = {SESSIONID:sessionId}
+
+    return HttpResponse(response_text, mimetype=JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_controller_stats(request, stattype):
+    """
+    This returns controller-level statistics/info from sdnplatform
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    url = 'http://127.0.0.1:8080/wm/core/controller/%s/json' % stattype
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_controller_storage_table_list(request):
+    """
+    This returns controller-level storage table list
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    url = 'http://127.0.0.1:8080/wm/core/storage/tables/json'
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_device(request):
+    if onos == 0:
+        return get_sdnplatform_query(request, "device")
+    else:
+        url = controller_url("onos", "topology", "hosts")
+        if request.META['QUERY_STRING']:
+            url += '?' + request.META['QUERY_STRING']
+        return get_sdnplatform_response(url)        
+
+@safe_rest_view
+def do_switches(request):
+    if onos == 0:
+        url = controller_url("core", "controller", "switches", "json")
+    else:
+        url = controller_url("onos", "topology", "switches")
+    if request.META['QUERY_STRING']:
+        url += '?' + request.META['QUERY_STRING']
+    return get_sdnplatform_response(url)        
+
+@safe_rest_view
+def do_routers(request):
+    if onos == 0:
+        url = controller_url("core", "controller", "switches", "json")
+    else:
+        url = controller_url("onos","segmentrouting", "routers")
+    if request.META['QUERY_STRING']:
+        url += '?' + request.META['QUERY_STRING']
+    return get_sdnplatform_response(url)        
+
+@safe_rest_view
+def do_router_stats(request, stattype, dpid):
+    """
+    This returns the subnets info about the specifed
+    router dpid. statetype should be 'port'.
+    """
+    #raise RestInvalidMethodException()
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    #url = controller_url('core', 'switch', dpid, stattype, 'json')
+    url = "http://localhost:8080/wm/onos/segmentrouting/router/%s/%s" % (dpid, stattype)
+    #raise RestInvalidMethodException(url)
+    #url = "http://localhost:8080/wm/onos/segementrouting/router/00:00:00:00:00:00:00:01/port"
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_mastership(request):
+    url = controller_url("onos", "registry", "switches" ,"json")
+    #url = "http://127.0.0.1:8080/wm/onos/registry/switches/json"
+    if request.META['QUERY_STRING']:
+        url += '?' + request.META['QUERY_STRING']
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_controller(request):
+    url = controller_url("onos", "registry", "controllers" ,"json")
+    #url = "http://127.0.0.1:8080/wm/onos/registry/switches/json"
+    if request.META['QUERY_STRING']:
+        url += '?' + request.META['QUERY_STRING']
+    return get_sdnplatform_response(url) 
+#'''
+
+@safe_rest_view
+def do_links(request):
+    if onos == 0:
+        url = controller_url("topology", "links", "json")
+    else:
+        url = controller_url("onos", "topology", "links")
+    if request.META['QUERY_STRING']:
+        url += '?' + request.META['QUERY_STRING']
+    return get_sdnplatform_response(url)        
+
+@safe_rest_view
+def do_vns_device_interface(request):
+    return get_sdnplatform_query(request, "vns/device-interface")
+
+@safe_rest_view
+def do_vns_interface(request):
+    return get_sdnplatform_query(request, "vns/interface")
+
+@safe_rest_view
+def do_vns(request):
+    return get_sdnplatform_query(request, "vns")
+
+@safe_rest_view
+def do_system_version(request):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    version = get_system_version_string()
+    response_text = simplejson.dumps([{ 'controller' : version }])
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+available_log_files = {
+    'syslog'           : '/var/log/syslog',
+    'sdnplatform'       : '/opt/sdnplatform/sdnplatform/log/sdnplatform.log',
+    'console-access'   : '/opt/sdnplatform/con/log/access.log',
+    'cassandra'        : '/opt/sdnplatform/db/log/system.log',
+    'authlog'          : '/var/log/auth.log',
+    'pre-start'        : '/tmp/pre-start',
+    'post-start'       : '/tmp/post-start',
+    # 'ftp'              : '/var/log/ftp.log',
+}
+
+available_log_commands = {
+    'dmesg'     : 'dmesg',
+    'process'   : 'ps lax'
+}
+
+@safe_rest_view
+def do_system_log_list(request):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    existing_logs = []
+    for (log_name, log_path) in available_log_files.items():
+        try:
+            log_file = open(log_path, 'r')
+            existing_logs.append({ 'log' : log_name })
+            log_file.close()
+        except Exception, e:
+            pass
+
+    print '??'
+    for log_name in available_log_commands.keys():
+        print 'ADD', log_name
+        existing_logs.append({ 'log' : log_name })
+    response_text = simplejson.dumps(existing_logs)
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+
+def generate_subprocess_output(cmd):
+
+    process = subprocess.Popen(cmd, shell=True,
+                                   stdout=subprocess.PIPE,
+                                   stderr=subprocess.STDOUT,
+                                   bufsize=1)
+    while True:
+        line = process.stdout.readline()
+        if line != None and line != "":
+            yield line
+        else:
+            break
+
+
+@safe_rest_view
+def do_system_log(request, log_name):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    print 'do system log', log_name
+
+    # manage command ouput differently
+    if log_name in available_log_commands:
+        cmd = available_log_commands[log_name]
+        print 'DOING COMMAND', cmd
+
+        return HttpResponse(generate_subprocess_output(cmd),
+                            TEXT_PLAIN_CONTENT_TYPE)
+        return
+
+    log_path = available_log_files.get(log_name)
+    if log_name == None:
+        raise RestInvalidLog('No such log: %s' % log_name)
+    
+    try:
+        log_file = open(log_path, 'r')
+    except Exception,e:
+        raise RestInvalidLog('Log does not exist: %s' % log_name)
+        
+    # use a generator so that the complete log is not ever held in memory
+    def response(log_name, file):
+        for line in file:
+            yield line
+        file.close()
+
+    return HttpResponse(response(log_name, log_file), TEXT_PLAIN_CONTENT_TYPE)
+
+
+@safe_rest_view
+def do_system_uptime(request):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    url = controller_url('core', 'system', 'uptime', 'json')
+    return get_sdnplatform_response(url)        
+
+
+def _collect_system_interfaces(lo = False):
+    from netifaces import interfaces, ifaddresses, AF_INET, AF_LINK
+    result = []
+    for iface in interfaces():
+        if iface.startswith('lo') and not lo:
+            continue # ignore loopback
+        addrs = ifaddresses(iface)
+        if AF_INET in addrs:
+            for addr in ifaddresses(iface)[AF_INET]:
+                result.append({'name'      : iface,
+                               'addr'      : addr.get('addr', ''),
+                               'netmask'   : addr.get('netmask', ''),
+                               'broadcast' : addr.get('broadcast', ''),
+                               'peer'      : addr.get('peer', '')})
+    return result
+
+
+def do_system_inet4_interfaces(request):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    response_text = simplejson.dumps(_collect_system_interfaces(lo = True))
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+
+@safe_rest_view
+def do_system_time_zone_strings(request, list_type):
+    import pytz
+    if list_type == 'common':
+        string_list = pytz.common_timezones
+    elif list_type == "all":
+        string_list = pytz.all_timezones
+    else:
+        raise RestResourceNotFoundException(request.path)
+    
+    response_text = simplejson.dumps(string_list)
+    
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_check_config(request):
+    config_check_state()
+    return get_successful_response('checked config')
+
+@safe_rest_view
+def do_local_controller_id(request):
+    if request.method == 'GET':
+        controller_id = get_local_controller_id()
+        if not controller_id:
+            raise Exception("Unspecified local controller id")
+        response_text = simplejson.dumps({'id': controller_id})
+    elif request.method == 'PUT':
+        put_data = json.loads(request.raw_post_data)
+        controller_id = put_data.get('id')
+        _result = exec_os_wrapper("ControllerId", 'set', [controller_id])
+        response_text = get_successful_response_data('updated')
+    else:
+        raise RestInvalidMethodException()
+    
+    response = HttpResponse(response_text, JSON_CONTENT_TYPE)
+    
+    return response
+
+@safe_rest_view
+def do_ha_failback(request):
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    _result = exec_os_wrapper("HAFailback", 'set', [])
+    response_text = get_successful_response_data('forced failback')
+    response = HttpResponse(response_text, JSON_CONTENT_TYPE)
+    return response
+
+def delete_ha_firewall_rules(ip):
+    rules = FirewallRule.objects.filter(action='allow', src_ip=ip)
+    rules.filter(port=80).delete()
+    rules.filter(proto='tcp', port=7000).delete()
+    rules.filter(proto='vrrp').delete()
+
+def cascade_delete_controller_node(controller_id):
+    ControllerAlias.objects.filter(controller=controller_id).delete()
+    ControllerDomainNameServer.objects.filter(controller=controller_id).delete()
+    for iface in ControllerInterface.objects.filter(controller=controller_id):
+        FirewallRule.objects.filter(interface=iface.id).delete()
+    ControllerInterface.objects.filter(controller=controller_id).delete()
+    Controller.objects.filter(id=controller_id).delete()
+
+# FIXME: this assume a single-interface design and will look for the IP on eth0
+#        need to fix this when we have a proper multi-interface design
+def get_controller_node_ip(controller_id):
+    node_ip = ''
+    iface = ControllerInterface.objects.filter(controller=controller_id, type='Ethernet', number=0)
+    if iface:
+        node_ip = iface[0].discovered_ip
+    return node_ip
+
+# This method is "external" facing
+# It is designed to be called by CLI or other REST clients
+# This should only run on the master node, where decommissioning of a remote node is initiated
+@safe_rest_view
+def do_decommission(request):
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    data = simplejson.loads(request.raw_post_data)
+    node_id = data['id']
+
+    # Disallow self-decommissioning
+    local_id = get_local_controller_id()
+    if local_id == node_id:
+        raise RestDecommissionException("Decommissioning of the master node is not allowed. " + \
+                                        "Please perform a failover first.")
+
+    try :
+        controller = Controller.objects.get(id=node_id)
+    except Controller.DoesNotExist:
+        raise RestDecommissionException("No controller found")
+
+    node_ip = get_controller_node_ip(node_id)
+
+    # Case 1: controller node has IP
+    if node_ip:
+        result = exec_os_wrapper("Decommission", 'set', [node_ip])
+        output = result['out'].strip()
+        if result['out'].strip().endswith('is already decommissioned'):
+            delete_ha_firewall_rules(node_ip)
+            cascade_delete_controller_node(node_id)
+
+    # Case 2: controller node has NO IP
+    else:
+        output = '%s is already decommissioned' % node_id
+        cascade_delete_controller_node(node_id)
+
+    jsondict = {}
+    jsondict['status'] = "OK"
+    jsondict['description'] = output
+    return HttpResponse(simplejson.dumps(jsondict), JSON_CONTENT_TYPE)
+
+# This method is "internal" facing
+# It is designed to be called only by sys/remove-node.sh
+# This should only run on the node being decommissioned (slave)
+@safe_rest_view
+def do_decommission_internal(request):
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    data = simplejson.loads(request.raw_post_data)
+    node_ip = data['ip']
+    exec_os_wrapper("DecommissionLocal", 'set', [node_ip])
+
+    jsondict = {}
+    jsondict['status'] = "OK"
+    return HttpResponse(simplejson.dumps(jsondict), JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_ha_provision(request):
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    data = simplejson.loads(request.raw_post_data)
+    node_ip = data['ip']
+    
+    try :
+        ci = ControllerInterface.objects.get(ip=node_ip)
+        id = ci.controller.id
+        print 'got id', id
+        try:
+            a = ControllerAlias.objects.get(controller=id)
+            alias = a.alias
+        except:
+            alias = '(no controller alias)'
+
+        print 'alias:', alias
+        raise RestProvisionException('ip address already in controller %s %s' %
+                                     (id, alias))
+        
+    except ControllerInterface.DoesNotExist:
+        id = uuid.uuid4().urn[9:]
+        print "generated id = ", id
+        c = Controller(id=id)
+        try:
+            c.save()
+        except:
+            # describe failure
+            raise RestProvisionException('can\t save controller')
+            pass
+        print "save controller"
+        ci = ControllerInterface(controller=c,
+                                 ip=node_ip,
+                                 discovered_ip=node_ip)
+        try:
+            ci.save()
+        except:
+            # describe failure
+            raise RestProvisionException('can\t save controllar interfacer')
+
+    for c in Controller.objects.all():
+        if c.id != id:
+            #if there are multiple interfaces, assume the
+            # ethernet0 interface is for management purpose 
+            # XXX this could be better.
+            iface = ControllerInterface.objects.get(controller=c.id,
+                                                    type='Ethernet',
+                                                    number=0)
+            ip = iface.ip
+            fw = FirewallRule(interface=iface, action='allow',
+                              src_ip=node_ip, port=80, proto='tcp')
+            try:
+                fw.save()
+            except:
+                # describe failure
+                raise RestProvisionException('can\t save firewall rule from master')
+                
+            fw = FirewallRule(interface=ci, action='allow',
+                              src_ip=ip, port=80, proto='tcp')
+            try:
+                fw.save()
+            except:
+                raise RestProvisionException('can\t save firewall from slave')
+        
+
+    response_text = get_successful_response_data(id)
+    response = HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+    return response
+
+
+def get_clustername():
+    name = os.popen("grep cluster_name /opt/sdnplatform/db/conf/cassandra.yaml | awk  '{print $2}'").readline()
+    # name may be '', perhaps this ought to None?
+    return name
+
+
+@safe_rest_view
+def do_clustername(request):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    response_text = simplejson.dumps([{ 'clustername' : get_clustername() }])
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+    
+    
+@safe_rest_view
+def do_local_ha_role(request):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    url = controller_url('core', 'role', 'json')
+    try:
+        response_text = urllib2.urlopen(url, timeout=2).read()
+        response = json.loads(response_text)
+    except Exception:
+        response = HttpResponse('{"role":"UNAVAILABLE"}', JSON_CONTENT_TYPE)
+        return response
+    # now determine our controller id
+    controller_id = get_local_controller_id()
+
+    # find all the interfaces
+    ifs = ControllerInterface.objects.filter(controller=controller_id)
+
+    for intf in ifs:
+        firewall_id = '%s|%s|%s' % (controller_id, intf.type, intf.number)
+
+        rules = FirewallRule.objects.filter(interface=firewall_id)
+        for rule in rules:
+            if rule.action == 'reject' and rule.proto == 'tcp' and rule.port == 6633:
+                if response['role'] in {'MASTER', 'SLAVE'}:
+                    response['role']+='-BLOCKED'
+
+    response['clustername'] = get_clustername()
+        
+    return HttpResponse(simplejson.dumps(response), JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_system_clock(request, local=True):
+    local_or_utc_str = 'local' if local else 'utc'
+    if request.method == 'GET':
+        result = exec_os_wrapper("DateTime", 'get', [local_or_utc_str])
+    elif request.method == 'PUT':
+        time_info = simplejson.loads(request.raw_post_data)
+        dt = datetime(**time_info)
+        new_date_time_string = dt.strftime('%Y:%m:%d:%H:%M:%S')
+        result = exec_os_wrapper("DateTime", 'set', [local_or_utc_str, new_date_time_string])
+    else:
+        raise RestInvalidMethodException()
+
+    if len(result) == 0:
+        raise Exception('Error executing date command')
+    
+    # The DateTime OS wrapper only has a single command so the return
+    # date/time is the first line of the first element of the out array
+    values = result['out'].strip().split(':')
+    date_time_info = {
+        'year': int(values[0]),
+        'month': int(values[1]),
+        'day': int(values[2]),
+        'hour': int(values[3]),
+        'minute': int(values[4]),
+        'second': int(values[5]),
+        'tz': values[6]
+    }
+    response_text = simplejson.dumps(date_time_info)
+    response = HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+    return response
+
+@safe_rest_view
+def do_instance(request, model_name,id=None):
+    """
+    This function handles both GET and PUT methods.
+    
+    For a GET request it returns a list of all of the instances of the
+    model corresponding to the specified type that match the specified
+    query parameters. If there are no query parameters then it returns
+    a list of all of the instances of the specified type. The names of
+    the query parameters can use the Django double underscore syntax
+    for doing more complicated tests than just equality
+    (e.g. mac__startswith=192.168).
+    
+    For a PUT request it can either update an existing instance or
+    insert one or more new instances. If there are any query parameters
+    then it assumes that its the update case and that the query
+    parameters identify exactly one instance. If that's not the case
+    then an error response is returned. For the update case any subset
+    of the fields can be updated with the PUT data. The format of the
+    PUT data is a JSON dictionary
+    """
+    
+    # FIXME: Hack to remap 'localhost' id for the controller-node model
+    # to the real ID for this controller
+    if model_name == 'controller-node' and id == 'localhost':
+        id = get_local_controller_id()
+        
+    # Lookup the model class associated with the specified name
+    model_info = rest_model_info_dict.get(model_name)
+    if not model_info:
+        raise RestInvalidDataTypeException(model_name)
+            
+    # Set up the keyword argument dictionary we use to filter the QuerySet.
+    filter_keyword_args = {}
+
+    jsonp_prefix = None
+    nolist = False
+    order_by = None
+    
+    # Now iterate over the query params and add further filter keyword arguments
+    query_param_dict = request.GET
+    for query_param_name, query_param_value in query_param_dict.items():
+        add_query_param = False
+        query_param_name = str(query_param_name)
+        query_param_value = str(query_param_value)
+        if query_param_name == 'callback': #switching to match up with jquery getJSON call naming convention.
+            jsonp_prefix = query_param_value
+        elif query_param_name == 'nolist':
+            if query_param_value not in ('False', 'false', '0', ''):
+                nolist = True
+        elif query_param_name == 'orderby':
+            order_by = query_param_value.split(',')
+            for i in range(len(order_by)):
+                name = order_by[i]
+                if name.startswith('-'):
+                    descending = True
+                    name = name[1:]
+                else:
+                    descending = False
+                field_info = model_info.rest_name_dict.get(name)
+                if not field_info:
+                    raise RestInvalidOrderByException(name)
+                name = field_info.name
+                if descending:
+                    name = '-' + name
+                order_by[i] = name
+        elif query_param_name in model_info.rest_name_dict:
+            field_info = model_info.rest_name_dict.get(query_param_name)
+            # For booleans, translate True/False strings into 0/1.
+            if field_info and type(field_info.django_field_info) == BooleanField:
+                if query_param_value.lower() == 'false':
+                    query_param_value = 0
+                elif query_param_value.lower() == 'true':
+                    query_param_value = 1
+            query_param_name = field_info.name
+            if model_name == 'controller-node' and \
+              query_param_name == 'id' and query_param_value == 'localhost':
+                query_param_value = get_local_controller_id()
+            if model_name in 'controller-interface' and \
+              query_param_name == 'controller' and \
+              query_param_value == 'localhost':
+                query_param_value = get_local_controller_id()
+            add_query_param = True
+        else:
+            double_underscore_start = query_param_name.find("__")
+            if double_underscore_start >= 0:
+                rest_name = query_param_name[:double_underscore_start]
+                field_info = model_info.rest_name_dict.get(rest_name)
+                if field_info:
+                    operation = query_param_name[double_underscore_start:]
+                    query_param_name = field_info.name
+                    if type(field_info.django_field_info) == ForeignKey:
+                        query_param_name = query_param_name + '__' + field_info.django_field_info.rel.field_name
+                    # Substitute in the model field name for the (possible renamed) rest name
+                    query_param_name += operation
+                    add_query_param = True
+        if add_query_param:
+            filter_keyword_args[query_param_name] = query_param_value
+
+    if id != None:
+        if len(filter_keyword_args) > 0:
+            raise RestInvalidFilterParameterException(filter_keyword_args.keys()[0])
+        try:
+            get_args = {model_info.primary_key:id}
+            instance = model_info.model_class.objects.get(**get_args)
+            instance_list = (instance,)
+            nolist = True
+        except model_info.model_class.DoesNotExist,e:
+            raise RestResourceNotFoundException(request.path)
+        except model_info.model_class.MultipleObjectsReturned, exc:
+            # traceback.print_exc()
+            raise RestInternalException(exc)
+    elif (request.method != 'PUT') or (len(filter_keyword_args) > 0):
+        # Get the QuerySet based on the keyword arguments we constructed
+        instance_list = model_info.model_class.objects.filter(**filter_keyword_args)
+        if order_by:
+            instance_list = instance_list.order_by(*order_by)
+    else:
+        # We're inserting new objects, so there's no need to do a query
+        instance_list = None
+        
+    response_content_type = JSON_CONTENT_TYPE
+    
+    if request.method == 'GET':
+        json_response_data = []
+        for instance in instance_list:
+            json_instance = {}
+            for field_info in model_info.field_name_dict.values():
+                # Made some minor edits to deal with a) fields that are empty and b) fields that are not strings -Kyle
+                # Changed this to only do an explicit string conversion if it's a unicode string.
+                # The controller is expecting to get the unstringified value (e.g. for boolean values)
+                # Not sure if this will break things in the UI, but we'll need to resolve how
+                # we want to handle this. Also, how do we want to handle unicode strings? -- robv
+                field_name = field_info.name
+                if type(field_info.django_field_info) == ForeignKey:
+                    field_name += '_id'
+                value = instance.__dict__.get(field_name)
+                if value != None:
+                    if field_info.json_serialize:
+                        value = str(value)
+                    json_instance[field_info.rest_name] = value
+            json_response_data.append(json_instance)
+        
+        # If the nolist query param was enabled then check to make sure
+        # that there was only a single instance in the response list and,
+        # if so, unpack it from the list
+        if nolist:
+            if len(json_response_data) != 1:
+                raise RestNoListResultException()
+            json_response_data = json_response_data[0]
+        
+        # Convert to json
+        response_data = simplejson.dumps(json_response_data)
+        
+        # If the jsonp query parameter was specified, wrap the data with
+        # the jsonp prefix
+        if jsonp_prefix:
+            response_data = jsonp_prefix + '(' + response_data + ')'
+            # We don't really know what the content type is here, but it's typically javascript
+            response_content_type = TEXT_JAVASCRIPT_CONTENT_TYPE
+    elif request.method == 'PUT':
+        response_data = get_successful_response_data('saved')
+        response_content_type = JSON_CONTENT_TYPE
+        
+        begin_batch_notification()
+        json_object = simplejson.loads(request.raw_post_data)
+        if instance_list is not None:
+
+            # don't allow the ip address of the first interface to
+            # be updated once it is set.  This really applies to
+            # the interface cassandra uses to sync the db.
+            if model_name == 'controller-interface':
+                for instance in instance_list:
+                    if instance.number == 0 and instance.ip != '':
+                        if 'ip' in json_object and json_object['ip'] != instance.ip:
+                            raise RestModelException("In this version, ip-address of primary interface can't be updated after initial configuration")
+
+            # In this case the URL includes query parameter(s) which we assume
+            # narrow the request to the instances of the model to be updated
+            # updated with the PUT data. So we're updating existing instances
+            
+            # If it's a list with one element then extract the single element
+            if (type(json_object) == list) and (len(json_object) == 1):
+                json_object = json_object[0]
+                
+            # We're expecting a dictionary where the keys match the model field names
+            # If the data isn't a dictionary then return an error
+            if type(json_object) != dict:
+                raise RestInvalidPutDataException() # TODO: Should return something different here
+            
+            # Set the fields in the model instance with the data from the dictionary
+            for instance in instance_list:
+                for rest_name, value in json_object.items():
+                    if not rest_name in model_info.rest_name_dict:
+                        raise RestModelException("Model '%s' has no field '%s'" % 
+                                                 (model_name, rest_name))
+                    field_info = model_info.rest_name_dict[rest_name]
+                    field_name = str(field_info.name)   # FIXME: Do we need the str cast?
+                    if type(field_info.django_field_info) == ForeignKey:
+                        field_name += '_id'
+                    # TODO: Does Django still not like unicode strings here?
+                    if type(value) == unicode:
+                        value = str(value)
+                    instance.__dict__[field_name] = value
+                # Save the updated model instance
+                try:
+                    instance.full_clean()
+                    instance.save()
+                except ValidationError, err:
+                    handle_validation_error(model_info, err)
+                    #raise RestValidationException(err)
+                except Exception, exc:
+                    raise RestSaveException(exc)
+        else:
+            # In this case no query parameters or id were specified so we're inserting new
+            # instances into the database. The PUT data can be either a list of new
+            # items to add (i.e. top level json object is a list) or else a single
+            # new element (i.e. top-level json object is a dict).
+            #print "creating object(s)"
+
+            # To simplify the logic below we turn the single object case into a list
+            if type(json_object) != list:
+                json_object = [json_object]
+            
+            # Create new model instances for all of the items in the list
+            for instance_data_dict in json_object:
+                # We expect the data to be a dictionary keyed by the field names
+                # in the model. If it's not a dict return an error
+                if type(instance_data_dict) != dict:
+                    raise RestInvalidPutDataException()
+                
+                converted_dict = {}
+                
+                # Now add the fields specified in the PUT data
+                for rest_name, value in instance_data_dict.items():
+
+                    #print "  processing " + str(name) + " " + str(value)
+
+                    if not rest_name in model_info.rest_name_dict:
+                        raise RestModelException("Model '%s' has no field '%s'" % 
+                                                 (model_name, rest_name))
+                    field_info = model_info.rest_name_dict[rest_name]
+                    # simplejson uses unicode strings when it loads the objects which
+                    # Django doesn't like that, so we convert these to ASCII strings
+                    if type(rest_name) == unicode:
+                        rest_name = str(rest_name)
+                    if type(value) == unicode:
+                        value = str(value)
+                    field_name = field_info.name
+                    # FIXME: Hack to remap localhost controller node id alias to the actual
+                    # ID for the controller node. We shouldn't be doing this here (this code
+                    # shouldn't have anything about specific models), but it's the easiest
+                    # way to handle it for now and this code is likely going away sometime
+                    # pretty soon (written in May, 2012, let's see how long "pretty soon"
+                    # is :-) )
+                    if model_name == 'controller-node' and field_name == 'id' and value == 'localhost':
+                        value = get_local_controller_id()
+                    if type(field_info.django_field_info) == ForeignKey:
+                        field_name += '_id'
+                    converted_dict[field_name] = value
+                
+                try:
+                    instance = model_info.model_class(**converted_dict)
+                    instance.full_clean()
+                    instance.save()
+                except ValidationError, err:
+                    handle_validation_error(model_info, err)
+                    #raise RestValidationException(err)
+                except Exception, e:
+                    # traceback.print_exc()
+                    raise RestSaveException(e)
+                
+        end_batch_notification()
+    elif request.method == 'DELETE':
+        begin_batch_notification()
+        for instance in instance_list:
+            try:
+                instance.delete()
+            except ValidationError, err:
+                handle_validation_error(model_info, err)
+            except Exception, e:
+                raise RestException(e)
+        end_batch_notification()
+        response_data = "deleted"
+        response_content_type = 'text/plain'
+    else:
+        raise RestInvalidMethodException()
+    
+    return HttpResponse(response_data, response_content_type)
+
+def synthetic_controller_interface(model_name, query_param_dict, json_response_data):
+    # ---
+    if model_name == 'controller-interface':
+        # For controller-interfaces, when an ip address (netmask too)
+        # is left unconfigured, then it may be possible to associate
+        # ifconfig details with the interface.
+        #
+        # Since controller-interfaces has no mechanism to associate 
+        # specific ifconfig interfaces with rows, it's only possible to
+        # associate ip's when a single unconfigured ip address exists,
+        # using a process of elimination.  For all ip address in the
+        # ifconfig output, all statically configured controller-interface
+        # items are removed.  If only one result is left, and only
+        # one controller-interface has an unconfigured ip address
+        # (either a dhcp acquired address, or a static address where
+        # the ip address is uncofigured), the ifconfig ip address
+        # is very-likely to be the one associated with the 
+        # controller-interface row.
+
+        # Check the list of values to see if any are configured as dhcp
+        dhcp_count = 0
+        unconfigured_static_ip = 0
+        this_host = get_local_controller_id()
+
+        for entry in json_response_data:
+            if 'mode' in entry and entry['mode'] == 'dhcp' and \
+               'controller' in entry and entry['controller'] == this_host:
+                    dhcp_count += 1
+            if 'mode' in entry and entry['mode'] == 'static' and \
+               'ip' in entry and entry['ip'] == '':
+                    unconfigured_static_ip += 1
+        if dhcp_count + unconfigured_static_ip != 1:
+            for entry in json_response_data:
+                entry['found-ip']        = entry['ip']
+            return
+
+        need_controller_query = False
+        # determine whether the complete list of interfaces needs
+        # to be collected to associate the dhcp address.
+        for query_param_name, query_param_value in query_param_dict.items():
+            if query_param_name != 'controller':
+                need_controller_query = True
+            if query_param_name == 'controller' and \
+               query_param_value != this_host:
+                need_controller_query = True
+
+        if need_controller_query == False:
+            model_interfaces = [x for x in json_response_data
+                                if 'controller' in x and x['controller'] == this_host]
+        else:
+            # print 'need to collect all interfaces'
+            filter_keyword_args = {'controller' : this_host}
+            model_info = rest_model_info_dict.get(model_name)
+            instance_list = model_info.model_class.objects.filter(**filter_keyword_args)
+            response_data = []
+            for instance in instance_list:
+                data = {}
+                for field_info in model_info.field_name_dict.values():
+                    field_name = field_info.name
+                    if type(field_info.django_field_info) == ForeignKey:
+                        field_name += '_id'
+                    value = instance.__dict__.get(field_name)
+                    if value != None:
+                        if field_info.json_serialize:
+                            value = str(value)
+                        data[field_info.rest_name] = value
+                response_data.append(data)
+            model_interfaces = response_data
+
+        # Recompute the number of dhcp configured interfaces,
+        # model_interfaces is the collection of interface for 'this_host'
+        dhcp_count = 0
+        unconfigured_static_ip = 0
+        for ifs in model_interfaces:
+            if 'mode' in ifs and ifs['mode'] == 'dhcp':
+                dhcp_count += 1
+            if 'mode' in ifs and ifs['mode'] == 'static' and \
+               'ip' in ifs and ifs['ip'] == '':
+                    unconfigured_static_ip += 1
+
+        if dhcp_count + unconfigured_static_ip != 1:
+            # print "Sorry, %s dhcp + %s unconfigured static interfaces on %s" % \
+                  # (dhcp_count, unconfigured_static_ip, this_host)
+            # copy over static ip's
+            for entry in json_response_data:
+                entry['found-ip']        = entry['ip']
+            return
+
+        # collect current details for all the network interfaces
+        inet4_ifs = _collect_system_interfaces()
+
+        # iterate over the model_interfaces's interfaces, and 
+        # remove ip addresses from inet4_ifs which are static, and
+        # have the correct static value.
+
+        report_static = False
+        match_id = ''
+
+        for ifs in model_interfaces:
+            if 'mode' in ifs and ifs['mode'] == 'static':
+                if 'ip' in ifs and ifs['ip'] == '':
+                    # print "Unconfigured static ip for %s", ifs['id']
+                    match_id = ifs['id']
+                if 'ip' in ifs and ifs['ip'] != '':
+                    # find this address in the known addresses
+                    remove_entry = -1
+                    for index, inet4_if in enumerate(inet4_ifs):
+                        if inet4_if['addr'] == ifs['ip']:
+                            remove_entry = index
+                            break
+                    if remove_entry == -1:
+                        # print "Static ip %s not found" % ifs['ip']
+                        pass 
+                    else:
+                        del inet4_ifs[remove_entry]
+            elif 'mode' in ifs and ifs['mode'] == 'dhcp':
+                match_id = ifs['id']
+            else:
+                # ought to assert here, not_reached()
+                pass
+
+        # When only one entry is left in inet, its possible to do the assocation
+        if len(inet4_ifs) != 1:
+            # print "Incorrect number %s of inet4 interfaces left" % len(inet4_ifs)
+            pass
+
+        for entry in json_response_data:
+            entry['found-ip']        = entry['ip']
+            entry['found-netmask']   = entry['netmask']
+
+            if entry['id'] == match_id:
+                # make sure the address isn't set
+                if entry['ip'] == '':
+                    entry['found-ip']        = inet4_ifs[0]['addr']
+                    entry['found-netmask']   = inet4_ifs[0]['netmask']
+                    entry['found-broadcast'] = inet4_ifs[0]['broadcast']
+                else:
+                    # ought to assert here, not_reached()
+                    pass
+
+@safe_rest_view
+def do_synthetic_instance(request, model_name, id=None):
+    
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    # Lookup the model class associated with the specified name
+    model_info = rest_model_info_dict.get(model_name)
+    if not model_info:
+        raise RestInvalidDataTypeException(model_name)
+            
+    # Set up the keyword argument dictionary we use to filter the QuerySet.
+    filter_keyword_args = {}
+
+    jsonp_prefix = None
+    nolist = False
+    order_by = None
+    
+    # Now iterate over the query params and add further filter keyword arguments
+    query_param_dict = request.GET
+    for query_param_name, query_param_value in query_param_dict.items():
+        add_query_param = False
+        query_param_name = str(query_param_name)
+        query_param_value = str(query_param_value)
+        if query_param_name == 'callback': #switching to match up with jquery getJSON call naming convention.
+            jsonp_prefix = query_param_value
+        elif query_param_name == 'nolist':
+            if query_param_value not in ('False', 'false', '0', ''):
+                nolist = True
+        elif query_param_name == 'orderby':
+            order_by = query_param_value.split(',')
+            for i in range(len(order_by)):
+                name = order_by[i]
+                if name.startswith('-'):
+                    descending = True
+                    name = name[1:]
+                else:
+                    descending = False
+                field_info = model_info.rest_name_dict.get(name)
+                if not field_info:
+                    raise RestInvalidOrderByException(name)
+                name = field_info.name
+                if descending:
+                    name = '-' + name
+                order_by[i] = name
+        elif query_param_name in model_info.rest_name_dict:
+            field_info = model_info.rest_name_dict.get(query_param_name)
+            query_param_name = field_info.name
+            add_query_param = True
+        else:
+            double_underscore_start = query_param_name.find("__")
+            if double_underscore_start >= 0:
+                rest_name = query_param_name[:double_underscore_start]
+                field_info = model_info.rest_name_dict.get(rest_name)
+                if field_info:
+                    operation = query_param_name[double_underscore_start:]
+                    query_param_name = field_info.name
+                    if type(field_info.django_field_info) == ForeignKey:
+                        query_param_name = query_param_name + '__' + field_info.django_field_info.rel.field_name
+                    # Substitute in the model field name for the (possible renamed) rest name
+                    query_param_name += operation
+                    add_query_param = True
+        if add_query_param:
+            filter_keyword_args[query_param_name] = query_param_value
+
+    if id != None:
+        if len(filter_keyword_args) > 0:
+            raise RestInvalidFilterParameterException(filter_keyword_args.keys()[0])
+        try:
+            get_args = {model_info.primary_key:id}
+            instance = model_info.model_class.objects.get(**get_args)
+            instance_list = (instance,)
+            nolist = True
+        except model_info.model_class.DoesNotExist,e:
+            raise RestResourceNotFoundException(request.path)
+        except model_info.model_class.MultipleObjectsReturned, exc:
+            # traceback.print_exc()
+            raise RestInternalException(exc)
+    elif (request.method != 'PUT') or (len(filter_keyword_args) > 0):
+        # Get the QuerySet based on the keyword arguments we constructed
+        instance_list = model_info.model_class.objects.filter(**filter_keyword_args)
+        if order_by:
+            instance_list = instance_list.order_by(*order_by)
+    else:
+        # We're inserting new objects, so there's no need to do a query
+        instance_list = None
+        
+    response_content_type = JSON_CONTENT_TYPE
+    
+    # Syntheric types only do requests --
+    json_response_data = []
+    for instance in instance_list:
+        json_instance = {}
+        for field_info in model_info.field_name_dict.values():
+            # Made some minor edits to deal with a) fields that are empty and b) fields that are not strings -Kyle
+            # Changed this to only do an explicit string conversion if it's a unicode string.
+            # The controller is expecting to get the unstringified value (e.g. for boolean values)
+            # Not sure if this will break things in the UI, but we'll need to resolve how
+            # we want to handle this. Also, how do we want to handle unicode strings? -- robv
+            field_name = field_info.name
+            if type(field_info.django_field_info) == ForeignKey:
+                field_name += '_id'
+            value = instance.__dict__.get(field_name)
+            if value != None:
+                if field_info.json_serialize:
+                    value = str(value)
+                json_instance[field_info.rest_name] = value
+        json_response_data.append(json_instance)
+    
+    # ---
+    if model_name == 'controller-interface':
+        synthetic_controller_interface(model_name, query_param_dict, json_response_data)
+
+    # Convert to json
+    response_data = simplejson.dumps(json_response_data)
+    
+    # If the nolist query param was enabled then check to make sure
+    # that there was only a single instance in the response list and,
+    # if so, unpack it from the list
+    if nolist:
+        if len(json_response_data) != 1:
+            raise RestNoListResultException()
+        json_response_data = json_response_data[0]
+    
+    # If the jsonp query parameter was specified, wrap the data with
+    # the jsonp prefix
+    if jsonp_prefix:
+        response_data = jsonp_prefix + '(' + response_data + ')'
+        # We don't really know what the content type is here, but it's typically javascript
+        response_content_type = TEXT_JAVASCRIPT_CONTENT_TYPE
+
+    return HttpResponse(response_data, response_content_type)
+
+@safe_rest_view
+def do_user_data_list(request):
+    # Now iterate over the query params and add any valid filter keyword arguments
+    filter_keyword_args = {}
+    for query_param_name, query_param_value in request.GET.items():
+        query_param_name = str(query_param_name)
+        double_underscore_start = query_param_name.find("__")
+        if double_underscore_start >= 0:
+            attribute_name = query_param_name[:double_underscore_start]
+        else:
+            attribute_name = query_param_name
+            
+        # In the future, if we add support for things like mod_date, creation_date, etc.
+        # which would be supported in query params, then they'd be added to this list/tuple.
+        if attribute_name not in ('name',):
+            raise RestInvalidFilterParameterException(query_param_name)
+        filter_keyword_args[query_param_name] = query_param_value
+
+    instance_list = UserData.objects.filter(**filter_keyword_args)
+    
+    if request.method == 'GET':
+        user_data_info_list = []
+
+        # FIXME: robv: It's incorrect to *always* add this to the user data,
+        # because it means we're not respecting the filter query parameters.
+        # To work completely correctly we'd need to duplicate a lot of logic
+        # for processing the query parameters, which would be tedious.
+        # Should talk to Mandeep about why it was done this way. Maybe we
+        # should expose these special cases in a different URL/view.
+        for fn in ['startup-config', 'upgrade-config']:
+            try:
+                sc = "%s/run/%s" % (sdncon.SDN_ROOT, fn)
+                f = open(sc, 'r')
+                f.close()
+                t = time.strftime("%Y-%m-%d.%H:%M:%S",
+                                  time.localtime(os.path.getmtime(sc)))
+                instance_name = fn + '/timestamp=' + t + \
+                                '/version=1/length=' + \
+                                str(os.path.getsize(sc))
+                url_path = 'rest/v1/data/' + instance_name + '/'
+                            
+                user_data_info = { 'name' : instance_name,
+                                   'url_path' : url_path, }
+                user_data_info_list.append(user_data_info)
+            except:
+                pass
+
+        for instance in instance_list:
+            user_data_info = {'name': instance.name,
+                              'url_path': 'rest/v1/data/' + instance.name + '/'}
+            user_data_info_list.append(user_data_info)
+        
+        response_data = simplejson.dumps(user_data_info_list)
+    elif request.method == 'DELETE':
+        instance_list.delete()
+        response_data = {}
+        response_data['status'] = 'success'
+        response_data['message'] = 'user data deleted'
+        response_data = simplejson.dumps(response_data)
+        response_content_type = JSON_CONTENT_TYPE
+    else:
+        raise RestInvalidMethodException()
+        
+    return HttpResponse(response_data, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_user_data(request, name):
+    query_param_dict = request.GET
+    #
+    # Manage startup-config/update-config differently
+    if name.find('/') >= 0 and \
+       name.split('/')[0] in ['startup-config', 'upgrade-config']:
+        path = "%s/run/%s" % (sdncon.SDN_ROOT, name.split('/')[0])
+        response_data = {}
+
+        if request.method == 'GET':
+            with open(path, 'r') as f:
+                response_data = f.read()
+            response_content_type = "text/plain"
+        elif request.method == 'PUT':
+            try:
+                with open(path, 'w') as f:
+                    f.write(request.raw_post_data)
+                response_data['status'] = 'success'
+                response_data['message'] = 'user data updated'
+            except:
+                response_data['status'] = 'failure'
+                response_data['message'] = "can't write file"
+            response_content_type = JSON_CONTENT_TYPE
+            response_data = simplejson.dumps(response_data)
+        elif request.method == 'DELETE':
+            try:
+                f = open(path, "r")
+                f.close()
+            except:
+                raise RestResourceNotFoundException(request.path)
+
+            try:
+                os.remove(path)
+                response_data['status'] = 'success'
+                response_data['message'] = 'user data deleted'
+            except:
+                response_data['status'] = 'failure'
+                response_data['message'] = "can't delete file"
+            response_data = simplejson.dumps(response_data)
+            response_content_type = JSON_CONTENT_TYPE
+        else:
+            raise RestInvalidMethodException()
+            
+        return HttpResponse(response_data, response_content_type)
+            
+    
+    # Default values for optional query parameters
+    #private = False
+    binary = False
+    
+    for param_name, param_value in query_param_dict.items():
+        if param_name == 'binary':
+            if request.method != 'PUT':
+                raise RestInvalidQueryParameterException(name)
+            binary = param_value.lower() == 'true' or param_value == '1'
+        #elif param_name == 'private':
+        #    private = param_value
+        else:
+            raise RestInvalidQueryParameterException(param_name)
+    
+    # FIXME: Need HTTP basic/digest auth support for the following
+    # code to work.
+    #if private:
+    #    user = request.user
+    #else:
+    #    user = None
+    #if user != None and not user.is_authenticated():
+    #    raise RestAuthenticationRequiredException()
+    user = None
+    
+    # There's currently an issue with filtering on the user when using the
+    # Cassandra database backend. Since we don't support private per-user
+    # data right now, I'm just disabling filtering on the user and only
+    # filter on the name
+    #user_data_query_set = UserData.objects.filter(user=user, name=name)
+    user_data_query_set = UserData.objects.filter(name=name)
+
+    count = user_data_query_set.count()
+    if count > 1:
+        raise RestInternalException('Duplicate user data values for the same name')
+    
+    if request.method == 'GET':
+        if count == 0:
+            raise RestResourceNotFoundException(request.path)
+        user_data = user_data_query_set[0]
+        response_data = user_data.data
+        if user_data.binary:
+            response_data = base64.b64decode(response_data)
+        response_content_type = user_data.content_type
+    elif request.method == 'PUT':
+        content_type = request.META['CONTENT_TYPE']
+        if content_type == None:
+            if binary:
+                content_type = BINARY_DATA_CONTENT_TYPE
+            else:
+                content_type = JSON_CONTENT_TYPE
+        response_data = {}
+        if count == 1:
+            response_data['status'] = 'success'
+            response_data['message'] = 'user data updated'
+            user_data = user_data_query_set[0]
+        else:
+            response_data['status'] = 'success'
+            response_data['message'] = 'user data created'
+            user_data = UserData(user=user,name=name)
+        user_data.binary = binary
+        user_data.content_type = content_type
+        data = request.raw_post_data
+        if binary:
+            data = base64.b64encode(data)
+        user_data.data = data
+        user_data.save()
+        response_data = simplejson.dumps(response_data)
+        response_content_type = JSON_CONTENT_TYPE
+    elif request.method == 'DELETE':
+        if count == 0:
+            raise RestResourceNotFoundException(request.path)
+        user_data = user_data_query_set[0]
+        user_data.delete()
+        response_data = {}
+        response_data['status'] = 'success'
+        response_data['message'] = 'user data deleted'
+        response_data = simplejson.dumps(response_data)
+        response_content_type = JSON_CONTENT_TYPE
+    else:
+        raise RestInvalidMethodException()
+   
+    return HttpResponse(response_data, response_content_type)
+
+@safe_rest_view
+def do_sdnplatform_tunnel_manager(request, dpid=None):
+    """
+    This returns realtime statistics from sdnplatform
+    """
+
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    if dpid == None:
+        raise RestInvalidMethodException()
+
+    print 'DPID', dpid
+    if dpid == 'all':
+        url = controller_url('vns', 'tunnel-manager', 'all', 'json')
+    else:
+        url = controller_url('vns', 'tunnel-manager', 'switch='+dpid, 'json')
+
+    response_text = urllib2.urlopen(url).read()
+    entries = simplejson.loads(response_text)
+
+    if 'error' in entries and entries['error'] != None:
+        RestInternalException(entries['error'])
+
+    return HttpResponse(json.dumps(entries['tunnMap']), JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_sdnplatform_controller_summary(request):
+    """
+    This returns summary statistics from sdnplatform modules
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    url = controller_url('core', 'controller', 'summary', 'json')
+    return get_sdnplatform_response(url)
+
+def filter_queries(choice_list, param_dict):
+    return dict([[x, param_dict[x]] for x in choice_list
+                if x in param_dict and param_dict[x] != 'all'])
+
+@safe_rest_view
+def do_reload(request):
+    """
+    This calls an oswrapper that reloads the box.
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    exec_os_wrapper("ReloadController", 'set', [])
+    response_text = '{"status":"reloading"}'
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_resetbsc(request):
+    """
+    This calls an oswrapper that resets the box.
+    """
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    exec_os_wrapper("ResetBsc", 'set', [])
+    response_text = '{"status":"resetting"}'
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_abort_upgrade(request):
+    """
+    This calls an oswrapper that reloads the box.
+    """
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    controller_id = get_local_controller_id()
+    controller = Controller.objects.get(id=controller_id)
+    if controller.status != 'Upgrading':
+        raise RestUpgradeException("No Upgrade pending")
+    exec_os_wrapper("AbortUpgrade", 'set', [])
+    controller.status = 'Ready'
+    controller.save()
+    response_text = '{"status":"Ready"}'
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_config_rollback(request):
+    data = simplejson.loads(request.raw_post_data)
+    path = data['path']
+    print "Executing config rollback with config @", path
+    
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    exec_os_wrapper("RollbackConfig", 'set', [path])
+    response_text = get_successful_response_data('prepared config rollbacked')
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_upload_data(request):
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    data = simplejson.loads(request.raw_post_data)
+    content = data['data']
+    path = data['dst']
+    print "Executing config rollback with config @", path
+    
+    exec_os_wrapper("WriteDataToFile", 'set', [content, path])
+    response_text = get_successful_response_data('written data')
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_diff_config(request):
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    data = simplejson.loads(request.raw_post_data)
+    config1 = data['config-1']
+    config2 = data['config-2']
+    print "diffing '%s' with '%s'" %(config1, config2)
+    
+    result = exec_os_wrapper("DiffConfig", 'set', [config1, config2])
+    return HttpResponse(simplejson.dumps(result), JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_extract_upgrade_pkg_manifest(request):
+    """
+    This calls an oswrapper that extracts the upgrade package.
+    This returns the install package 'manifest'.
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    exec_os_wrapper("GetLatestUpgradePkg", 'get', [])
+    output = exec_os_wrapper("CatUpgradeImagesFile", 'get')
+    upgradePkg = output['out'].strip()
+    exec_os_wrapper("ExtractUpgradePkgManifest", 'set', [upgradePkg])
+    output = exec_os_wrapper("ExtractUpgradePkgManifest", 'get')
+    manifest = output['out']
+    return HttpResponse(manifest, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_extract_upgrade_pkg(request):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    exec_os_wrapper("GetLatestUpgradePkg", 'get', [])
+    output = exec_os_wrapper("CatUpgradeImagesFile", 'get')
+    upgradePkg = output['out'].strip()
+    exec_os_wrapper("ExtractUpgradePkg", 'set', [upgradePkg])
+    return HttpResponse('{"status": "OK"}', JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_get_upgrade_pkg(request):
+    """
+    This calls an oswrapper to get the latest upgrade
+    package uploaded to the controller.
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    exec_os_wrapper("GetLatestUpgradePkg", 'get')
+    result = exec_os_wrapper("CatUpgradeImagesFile", 'get')
+    jsondict = {'file': result['out'].strip()}
+    return HttpResponse(simplejson.dumps(jsondict), JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_cleanup_old_pkgs(request):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    exec_os_wrapper("CleanupOldUpgradeImages", 'get')
+    return HttpResponse('{"status": "OK"}', JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_execute_upgrade_step(request):
+    """
+    Executes a particular upgrade step according to the
+    upgrade package manifest.
+    """
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+
+    put_data = json.loads(request.raw_post_data)
+    imageName = put_data.get('imageName')
+    stepNum = put_data.get('step')
+    force = put_data.get('force')
+    
+    args = [stepNum, imageName]
+    if force:
+        args.append("--force")
+    result = exec_os_wrapper("ExecuteUpgradeStep", 'get', 
+                             args)
+    jsondict = {}
+    if len(str(result['err']).strip()) > 0:
+        jsondict['status'] = "ERROR"
+        jsondict['description'] = str(result['err']).strip()
+    else:
+        jsondict['status'] = "OK"
+        jsondict['description'] = str(result['out']).strip()
+
+    return HttpResponse(simplejson.dumps(jsondict), JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_sdnplatform_tunnel_config(request):    
+    if request.method != 'PUT' and request.method != 'DELETE':
+        raise RestInvalidMethodException()
+
+    url = controller_url('onos', 'segmentrouting', 'tunnel')
+    post_data = request.raw_post_data
+    put_request = urllib2.Request(url, post_data)
+    method = request.method
+    if method == 'PUT':
+        method = 'POST'
+    put_request.get_method = lambda: method
+    put_request.add_header('Content-Type', 'application/json')
+    response = urllib2.urlopen(put_request)
+    response_text = response.read()
+    response = HttpResponse(response_text, JSON_CONTENT_TYPE)
+    
+    return response
+
+@safe_rest_view
+def do_sdnplatform_policy_config(request):    
+    if request.method != 'PUT' and request.method != 'DELETE':
+        raise RestInvalidMethodException()
+
+    url = controller_url('onos', 'segmentrouting', 'policy')
+    post_data = request.raw_post_data
+    put_request = urllib2.Request(url, post_data)
+    method = request.method
+    if method == 'PUT':
+        method = 'POST'
+    put_request.get_method = lambda: method
+    put_request.add_header('Content-Type', 'application/json')
+    response = urllib2.urlopen(put_request)
+    response_text = response.read()
+    response = HttpResponse(response_text, JSON_CONTENT_TYPE)
+    
+    return response
+
+@safe_rest_view
+def do_show_tunnel(request):    
+    #if request.method != 'GET':
+    #    raise RestInvalidMethodException()
+
+    url = controller_url('onos', 'segmentrouting','tunnel')
+    if request.META['QUERY_STRING']:
+        url += '?' + request.META['QUERY_STRING']
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_show_policy(request):    
+    #if request.method != 'GET':
+    #    raise RestInvalidMethodException()
+
+    url = controller_url('onos', 'segmentrouting','policy')
+    if request.META['QUERY_STRING']:
+        url += '?' + request.META['QUERY_STRING']
+    return get_sdnplatform_response(url)
\ No newline at end of file
diff --git a/sdncon/runtests.py b/sdncon/runtests.py
new file mode 100755
index 0000000..afa7b3e
--- /dev/null
+++ b/sdncon/runtests.py
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+import os, sys
+os.environ['DJANGO_SETTINGS_MODULE'] = 'sdncon.settings'
+sys.path.insert(0, os.path.dirname(__file__))
+
+test_labels = ['clusterAdmin', "contenttypes", "sessions", "messages"]
+smoke_test_labels = ["admin", "rest", "controller", "stats"]
+
+def runtests(tests=test_labels):
+    import django.test.utils, django.conf
+    test_runner = django.test.utils.get_runner(django.conf.settings)
+    if hasattr(test_runner, "run_tests"):
+        test_runner = test_runner(verbosity=2).run_tests
+    failures = test_runner(tests)
+    sys.exit(0 if failures == 0 else 1)
+
+def runtests_smoke():
+    return runtests(smoke_test_labels)
diff --git a/sdncon/sdncon b/sdncon/sdncon
new file mode 100644
index 0000000..e7fcf37
--- /dev/null
+++ b/sdncon/sdncon
Binary files differ
diff --git a/sdncon/sdncon.egg-info/PKG-INFO b/sdncon/sdncon.egg-info/PKG-INFO
new file mode 100644
index 0000000..0f270f8
--- /dev/null
+++ b/sdncon/sdncon.egg-info/PKG-INFO
@@ -0,0 +1,10 @@
+Metadata-Version: 1.0
+Name: sdncon
+Version: 0.1.0
+Summary: UNKNOWN
+Home-page: UNKNOWN
+Author: UNKNOWN
+Author-email: UNKNOWN
+License: UNKNOWN
+Description: UNKNOWN
+Platform: UNKNOWN
diff --git a/sdncon/sdncon.egg-info/SOURCES.txt b/sdncon/sdncon.egg-info/SOURCES.txt
new file mode 100644
index 0000000..4001b64
--- /dev/null
+++ b/sdncon/sdncon.egg-info/SOURCES.txt
@@ -0,0 +1,113 @@
+MANIFEST.in
+setup.py
+./__init__.py
+./apploader.py
+./constants.py
+./extract_model.py
+./manage.py
+./settings.py
+./urls.py
+./apps/cstats/__init__.py
+./apps/cstats/models.py
+./apps/cstats/urls.py
+./apps/cstats/views.py
+./apps/cstats/static/css/timeselector.css
+./apps/docs/__init__.py
+./apps/docs/urls.py
+./apps/docs/views.py
+./apps/docs/static/pdf/user-guide.pdf
+./apps/logs/__init__.py
+./apps/logs/models.py
+./apps/logs/urls.py
+./apps/logs/views.py
+./clusterAdmin/__init__.py
+./clusterAdmin/admin.py
+./clusterAdmin/middleware.py
+./clusterAdmin/models.py
+./clusterAdmin/utils.py
+./clusterAdmin/views.py
+./controller/__init__.py
+./controller/admin.py
+./controller/config.py
+./controller/firewall.py
+./controller/models.py
+./controller/notification.py
+./controller/oswrapper.py
+./controller/views.py
+./coreui/__init__.py
+./coreui/models.py
+./coreui/urls.py
+./coreui/views.py
+./coreui/img/bsnlogo-l.png
+./coreui/img/bsnlogo-s.png
+./coreui/img/bsnlogo.png
+./coreui/img/footer.png
+./coreui/img/gradient.png
+./coreui/img/handandsticker2.jpg
+./coreui/img/loading-circle.gif
+./coreui/templatetags/__init__.py
+./coreui/templatetags/gravatar.py
+./rest/RestApiTestData.py
+./rest/__init__.py
+./rest/config.py
+./rest/jsonview.py
+./rest/models.py
+./rest/poll.py
+./rest/validators.py
+./rest/views.py
+./statdropd/__init__.py
+./statdropd/models.py
+./statdropd/views.py
+./stats/__init__.py
+./stats/data.py
+./stats/models.py
+./stats/statsFiller.py
+./stats/utils.py
+./stats/views.py
+./stats_metadata/__init__.py
+./stats_metadata/of_stats_metadata.py
+./stats_metadata/os_stats_metadata.py
+./syncd/__init__.py
+./syncd/models.py
+./syncd/views.py
+apps/cstats/static/css/timeselector.css
+apps/docs/static/pdf/user-guide.pdf
+coreui/img/bsnlogo-l.png
+coreui/img/bsnlogo-s.png
+coreui/img/bsnlogo.png
+coreui/img/footer.png
+coreui/img/gradient.png
+coreui/img/handandsticker2.jpg
+coreui/img/loading-circle.gif
+sdncon.egg-info/PKG-INFO
+sdncon.egg-info/SOURCES.txt
+sdncon.egg-info/dependency_links.txt
+sdncon.egg-info/top_level.txt
+ui/static/favicon.ico
+ui/static/css/table.css
+ui/static/css/thirdparty/jquery-ui-1.10.2.custom.css
+ui/static/css/thirdparty/jquery-ui-1.10.2.custom.min.css
+ui/static/css/thirdparty/images/animated-overlay.gif
+ui/static/css/thirdparty/images/ui-bg_flat_100_FFFFFF_40x100.png
+ui/static/css/thirdparty/images/ui-bg_flat_45_e5e5e5_40x100.png
+ui/static/css/thirdparty/images/ui-bg_flat_50_00a0df_40x100.png
+ui/static/css/thirdparty/images/ui-bg_flat_50_fdb813_40x100.png
+ui/static/css/thirdparty/images/ui-bg_flat_55_999999_40x100.png
+ui/static/css/thirdparty/images/ui-bg_flat_75_aaaaaa_40x100.png
+ui/static/css/thirdparty/images/ui-bg_flat_75_e5e5e5_40x100.png
+ui/static/css/thirdparty/images/ui-bg_glass_55_f8da4e_1x400.png
+ui/static/css/thirdparty/images/ui-bg_gloss-wave_45_e14f1c_500x100.png
+ui/static/css/thirdparty/images/ui-icons_4d4d4f_256x240.png
+ui/static/css/thirdparty/images/ui-icons_f47d20_256x240.png
+ui/static/css/thirdparty/images/ui-icons_f7a50d_256x240.png
+ui/static/css/thirdparty/images/ui-icons_fcd113_256x240.png
+ui/static/images/logo_opendaylight.png
+ui/static/images/refresh.png
+ui/static/js/topology.js
+ui/static/js/thirdparty/jit.js
+ui/static/js/thirdparty/jquery-1.9.1.js
+ui/static/js/thirdparty/jquery-1.9.1.min.js
+ui/static/js/thirdparty/jquery-ui-1.10.2.custom.js
+ui/static/js/thirdparty/jquery-ui-1.10.2.custom.min.js
+ui/templates/base.html
+ui/templates/index.html
\ No newline at end of file
diff --git a/sdncon/sdncon.egg-info/dependency_links.txt b/sdncon/sdncon.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/sdncon/sdncon.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/sdncon/sdncon.egg-info/top_level.txt b/sdncon/sdncon.egg-info/top_level.txt
new file mode 100644
index 0000000..7b7a30a
--- /dev/null
+++ b/sdncon/sdncon.egg-info/top_level.txt
@@ -0,0 +1 @@
+sdncon
diff --git a/sdncon/settings.py b/sdncon/settings.py
new file mode 100755
index 0000000..97f766e
--- /dev/null
+++ b/sdncon/settings.py
@@ -0,0 +1,186 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+# Django settings for sdncon project.
+
+import os, sys
+#from cassandra.ttypes import ConsistencyLevel
+
+DEBUG = True
+DEBUG_PROPAGATE_EXCEPTIONS = DEBUG
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+    # ('Your Name', 'your_email@domain.com'),
+)
+
+MANAGERS = ADMINS
+
+DATABASES = {
+    'default': {
+        #'ENGINE': 'django_cassandra.db',
+        'ENGINE': 'django.db.backends.sqlite3',
+        'NAME': 'sdncon',
+        'USER': '',                      # Not used with sqlite3.
+        'PASSWORD': '',                  # Not used with sqlite3.
+        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
+        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
+    }
+}
+
+# Settings for accessing the stats database/keyspace.
+# This does not go through the usual Django model/database layer, but
+# instead accesses Cassandra directly.
+STATS_DATABASE = {
+    'NAME': 'sdnstats',
+    #'HOST': '',
+    #'USER': '',
+    #'PASSWORD': '',
+    #'CASSANDRA_REPLICATION_FACTOR': 1
+}
+
+# Local time zone for this installation. Choices can be found here:
+# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
+# although not all choices may be available on all operating systems.
+# On Unix systems, a value of None will cause Django to use the same
+# timezone as the operating system.
+# If running in a Windows environment this must be set to the same as your
+# system time zone.
+#TIME_ZONE = 'America/Los_Angeles'
+TIME_ZONE = None
+
+# Language code for this installation. All choices can be found here:
+# http://www.i18nguy.com/unicode/language-identifiers.html
+LANGUAGE_CODE = 'en-us'
+
+SITE_ID = '1'
+
+# Tell Django where is the profile object
+#AUTH_PROFILE_MODULE = "sdncon.account.UserProfile"
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = True
+
+# If you set this to False, Django will not format dates, numbers and
+# calendars according to the current locale
+USE_L10N = True
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+SDN_ROOT = "/opt/sdnplatform" if not 'SDN_ROOT' in os.environ else os.environ['SDN_ROOT']
+MEDIA_ROOT = "%s/con/lib/python/django/contrib/admin/media/" % SDN_ROOT
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+# Examples: "http://media.lawrence.com", "http://example.com/media/"
+MEDIA_URL = ''
+STATIC_URL = '/static/'
+
+# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
+# trailing slash.
+# Examples: "http://foo.com/media/", "/media/".
+ADMIN_MEDIA_PREFIX = '/media/'
+
+# URL prefixes exempted from login requirements
+EXEMPT_URLS = ['/coreui/static/', '/coreui/img/', '/favicon.ico']
+
+# Make this unique, and don't share it with anybody.
+SECRET_KEY = 'p+7!f6@8ry2%faunco@u@$wzq7_jpyw4w7+sn=&xpuvo%2!uw('
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+    'django.template.loaders.filesystem.Loader',
+    'django.template.loaders.app_directories.Loader',
+#     'django.template.loaders.eggs.Loader',
+)
+
+from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS as GLOBAL_TEMPLATE_CONTEXT_PROCESSORS
+TEMPLATE_CONTEXT_PROCESSORS = GLOBAL_TEMPLATE_CONTEXT_PROCESSORS + (
+    'sdncon.clusterAdmin.utils.uicontext',
+)
+
+MIDDLEWARE_CLASSES = (
+    'sdncon.HARedirectMiddleWare',
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'sdncon.clusterAdmin.middleware.ClusterAuthenticate',
+    'sdncon.clusterAdmin.middleware.RequireAuthMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'sdncon.SDNConAppLoaderMiddleWare',
+)
+
+# Django uses browser-length cookies that expire as soon as the user closes the browser.
+SESSION_EXPIRE_AT_BROWSER_CLOSE = True
+SESSION_COOKIE_AGE = 2592000 # 30 days, in seconds
+
+ROOT_URLCONF = 'sdncon.urls'
+
+TEMPLATE_DIRS = (
+    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
+    # Always use forward slashes, even on Windows.
+    # Don't forget to use absolute paths, not relative paths.
+    os.path.dirname(__file__),
+    os.path.join(os.path.dirname(__file__),'clusterAdmin/templates'),
+)
+
+# Include applications dynamically from the apps folder
+
+APP_DIR = os.path.join(os.path.dirname(__file__),'apps')
+sys.path.append(APP_DIR)
+
+apps_array = [
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.staticfiles',
+    #'django.contrib.sites',
+    'django.contrib.messages',
+    # Uncomment the next line to enable the admin:
+    'django.contrib.admin',
+    'djangotoolbox',
+    'sdncon.rest',
+    'sdncon.controller',
+    #'django_cassandra',
+    'sdncon.coreui',
+    'sdncon.clusterAdmin',
+    #'sdncon.account',
+    'sdncon.ui',
+    'sdncon.stats',
+    'sdncon.syncd',
+    'sdncon.statdropd'
+]
+
+directory = os.listdir(APP_DIR)
+for filename in directory:
+    if not filename.startswith('.'):
+        apps_array.append(os.path.basename(filename))
+
+INSTALLED_APPS = tuple(apps_array)
+
+STATS_METADATA_MODULES = []
+
+_stats_meatadata_dir_name = 'stats_metadata'
+_stats_metadata_dir = os.path.join(os.path.dirname(__file__), _stats_meatadata_dir_name)
+_directory = os.listdir(_stats_metadata_dir)
+
+for _filename in _directory:
+    _basename = os.path.basename(_filename)
+    if _basename.endswith('.py') and _basename != '__init__.py':
+        _module_name = os.path.splitext(_basename)[0]
+        STATS_METADATA_MODULES.append('sdncon.%s.%s' % (_stats_meatadata_dir_name, _module_name))
diff --git a/sdncon/setup.py b/sdncon/setup.py
new file mode 100755
index 0000000..e75dd16
--- /dev/null
+++ b/sdncon/setup.py
@@ -0,0 +1,56 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+import setuptools, os
+import sys
+
+os.environ['DJANGO_SETTINGS_MODULE'] = 'sdncon.settings'
+
+def find_files(dirs):
+    files = []
+    for dir in dirs:
+        l = len(os.path.join(*os.path.split(dir)[:-1])) + 1
+        for dirpath, dirnames, filenames in os.walk(dir):
+            for fn in filenames:
+                files.append(os.path.join(dirpath, fn)[l:])
+    return files
+
+want_smoke = False
+
+if sys.argv[-1] == '--smoke-tests-only':
+    want_smoke = True
+    del sys.argv[-1]
+
+setuptools.setup(
+    name="sdncon",
+    version="0.1.0",
+    package_dir={"sdncon": "."},
+    packages=["sdncon", "sdncon.controller", "sdncon.rest",
+              "sdncon.clusterAdmin", "sdncon.coreui", "sdncon.coreui.templatetags",
+              "sdncon.stats", "sdncon.stats_metadata",
+              "sdncon.statdropd", "sdncon.syncd",
+              "sdncon.apps.cstats", "sdncon.apps.logs",  
+              "sdncon.apps.docs", 
+             ],
+    package_data={"sdncon.coreui": find_files(["coreui/templates", "coreui/img", "coreui/static"]),
+                  "sdncon.clusterAdmin": find_files(["clusterAdmin/templates"]),
+                  "sdncon.apps.cstats": find_files(["apps/cstats/templates", "apps/cstats/img", "apps/cstats/static"]),
+                  "sdncon.apps.logs": find_files(["apps/logs/templates", "apps/logs/img", "apps/logs/static"]),
+                  "sdncon.apps.docs": find_files(["apps/docs/templates", "apps/docs/static"]),
+                  },
+    test_suite= "sdncon.runtests.runtests_smoke" if want_smoke \
+                    else "sdncon.runtests.runtests"
+    )
diff --git a/sdncon/statdropd/__init__.py b/sdncon/statdropd/__init__.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/sdncon/statdropd/__init__.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
diff --git a/sdncon/statdropd/models.py b/sdncon/statdropd/models.py
new file mode 100755
index 0000000..0e93490
--- /dev/null
+++ b/sdncon/statdropd/models.py
@@ -0,0 +1,79 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.db import models
+"""
+# Create your models here.
+class StatdropdConfig(models.Model):
+    
+    # id is set to the local cluster id.
+    id = models.CharField(
+        primary_key=True,
+        max_length=128)
+
+    # Enable dropping local data
+    enabled = models.BooleanField(
+        verbose_name='Enabled',
+        help_text='Is dropping local data enabled.',
+        default=True)
+
+    # Log level for the statdropd daemon process
+    log_level = models.CharField(
+        max_length=32,
+        verbose_name='Log Level',
+        help_text='Log level for the statdropd daemon process',
+        default='warning')
+    
+    period = models.PositiveIntegerField(
+        verbose_name='Period',
+        help_text='How often (in seconds) to drop local stats/log data',
+        default=600)
+    
+    #retain_synced_data_duration = models.PositiveIntegerField(
+    #    verbose_name='Retain Synced Data',
+    #    help_text="How long should data that's been synced to the cloud be retained locally",
+    #    default=604800)
+    
+    retain_data_duration = models.PositiveIntegerField(
+        verbose_name='Retain Data Duration',
+        help_text="How long should data be retained locally",
+        default=604800)
+    
+    class Rest:
+        NAME = 'statdropd-config'
+        FIELD_INFO = (
+            {'name': 'log_level', 'rest_name': 'log-level'},
+            #{'name': 'retain_synced_data_duration', 'rest_name': 'retain-synced-data-duration'},
+            {'name': 'retain_data_duration', 'rest_name': 'retain-data-duration'},
+        )
+
+class StatdropdProgressInfo(models.Model):
+    
+    # id value is <controller-node-id>
+    id = models.CharField(
+        primary_key=True,
+        max_length=256)
+
+    last_drop_point = models.PositiveIntegerField(
+        verbose_name='Last Drop Point',
+        help_text='Last point when stats data was successfully dropped from the local controller node')
+    
+    class Rest:
+        NAME = 'statdropd-progress-info'
+        FIELD_INFO = (
+            {'name': 'last_drop_point', 'rest_name': 'last-drop-point'},
+        )
+"""
\ No newline at end of file
diff --git a/sdncon/statdropd/tests.py b/sdncon/statdropd/tests.py
new file mode 100755
index 0000000..6bef994
--- /dev/null
+++ b/sdncon/statdropd/tests.py
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.test import TestCase
diff --git a/sdncon/statdropd/views.py b/sdncon/statdropd/views.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/sdncon/statdropd/views.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
diff --git a/sdncon/stats/__init__.py b/sdncon/stats/__init__.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/sdncon/stats/__init__.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
diff --git a/sdncon/stats/data.py b/sdncon/stats/data.py
new file mode 100755
index 0000000..268422c
--- /dev/null
+++ b/sdncon/stats/data.py
@@ -0,0 +1,1160 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from cassandra.ttypes import KsDef, CfDef, InvalidRequestException, TTransport, \
+    SlicePredicate, SliceRange, ColumnParent, ConsistencyLevel, ColumnPath, \
+    Mutation, Deletion, KeyRange, Column, ColumnOrSuperColumn, SuperColumn
+from django.conf import settings
+from .utils import CassandraConnection
+import random
+import datetime
+import time
+from sdncon.controller.config import get_local_controller_id
+
+CONTROLLER_STATS_NAME = 'controller'
+SWITCH_STATS_NAME = 'switch'
+PORT_STATS_NAME = 'port'
+TARGET_INDEX_NAME = 'target_index'
+STATS_TYPE_INDEX_NAME = 'stats_type_index'
+
+STATS_COLUMN_FAMILY_NAME_SUFFIX = '_stats'
+STATS_TARGET_TYPE_PUT_DATA_SUFFIX = '-stats'
+
+STATS_BUCKET_PERIOD = 60*60*24*1000    # 1 day in milliseconds
+STATS_PADDED_COLUMN_TIME_LENGTH = len(str(STATS_BUCKET_PERIOD))
+
+EVENTS_COLUMN_FAMILY_NAME = 'events'
+EVENTS_BUCKET_PERIOD = 60*60*24*1000    # 1 day in milliseconds
+EVENTS_PADDED_COLUMN_TIME_LENGTH = len(str(EVENTS_BUCKET_PERIOD))
+
+THIRTY_SECOND_INTERVAL = 30 * 1000
+ONE_MINUTE_INTERVAL = 60 * 1000
+FIVE_MINUTE_INTERVAL = 5 * ONE_MINUTE_INTERVAL
+TEN_MINUTE_INTERVAL = 10 * ONE_MINUTE_INTERVAL
+ONE_HOUR_INTERVAL = 60 * ONE_MINUTE_INTERVAL
+FOUR_HOUR_INTERVAL = 4 * ONE_HOUR_INTERVAL
+ONE_DAY_INTERVAL = 24 * ONE_HOUR_INTERVAL
+ONE_WEEK_INTERVAL = 7 * ONE_DAY_INTERVAL
+FOUR_WEEK_INTERVAL = 4 * ONE_WEEK_INTERVAL
+
+DOWNSAMPLE_INTERVALS = (ONE_MINUTE_INTERVAL, TEN_MINUTE_INTERVAL,
+                        ONE_HOUR_INTERVAL, FOUR_HOUR_INTERVAL,
+                        ONE_DAY_INTERVAL, ONE_WEEK_INTERVAL,
+                        FOUR_WEEK_INTERVAL)
+
+WINDOW_INTERVALS = (THIRTY_SECOND_INTERVAL, ONE_MINUTE_INTERVAL,
+                    FIVE_MINUTE_INTERVAL, TEN_MINUTE_INTERVAL)
+
+VALUE_DATA_FORMAT = 'value'
+RATE_DATA_FORMAT = 'rate'
+
+
+class StatsException(Exception):
+    pass
+
+
+class StatsInvalidStatsDataException(StatsException):
+    def __init__(self):
+        super(StatsInvalidStatsDataException,self).__init__(
+            'Error adding stats data with incorrect format')
+
+
+class StatsDatabaseConnectionException(StatsException):
+    def __init__(self):
+        super(StatsDatabaseConnectionException,self).__init__(
+            'Error connecting to stats database')
+
+
+class StatsDatabaseAccessException(StatsException):
+    def __init__(self):
+        super(StatsDatabaseAccessException,self).__init__(
+            'Error accessing stats database')
+  
+class StatsNonnumericValueException(StatsException):
+    def __init__(self, value):
+        super(StatsNonnumericValueException,self).__init__(
+            'Invalid non-numeric stat value for rate or '
+            'average value computation: ' + str(value))
+
+
+class StatsRateComputationException(StatsException):
+    def __init__(self):
+        super(StatsRateComputationException,self).__init__(
+            'Error computing rate; not enough raw data')
+
+
+class StatsInvalidDataFormatException(StatsException):
+    def __init__(self, data_format):
+        super(StatsInvalidDataFormatException,self).__init__(
+            'Invalid data format: ' + str(data_format))
+
+
+class StatsInvalidStatsTimeRangeException(StatsException):
+    def __init__(self, start_time, end_time):
+        super(StatsInvalidStatsTimeRangeException,self).__init__(
+            'Invalid stats time range; start = %s; end = %s' %
+            (str(start_time), str(end_time)))
+
+
+class StatsInvalidStatsTypeException(StatsException):
+    def __init__(self, stats_type):
+        super(StatsInvalidStatsTypeException,self).__init__(
+            'Invalid stats type; name = %s' % str(stats_type))
+
+
+class StatsInvalidStatsMetadataException(StatsException):
+    def __init__(self, file_name):
+        super(StatsInvalidStatsMetadataException,self).__init__(
+            'Invalid stats metadata from file \"%s\"' % str(file_name))
+
+
+class StatsInternalException(StatsException):
+    def __init__(self, message):
+        super(StatsInternalException,self).__init__(
+            'Stats internal error: \"%s\"' % str(message))
+
+class StatsCreateColumnFamilyException(StatsException):
+    def __init__(self, name):
+        super(StatsCreateColumnFamilyException,self).__init__(
+            'Error creating column family; name = ' % name)
+        
+# The following code is a hack to get the stats code to use a freshly
+# created test keyspace when we're running the unit tests. I'm guessing
+# there must be some way to detect if we're running under the Django
+# (or Python) unit test framework, but I couldn't find any info about
+# how to do that. So for now, we just provide this function that the
+# unit tests must call before they make any stats call to get the stats
+# code to use the test keyspace instead of the normal production
+# keyspace. Bother.
+
+use_test_keyspace = False
+
+def set_use_test_keyspace():
+    global use_test_keyspace
+    use_test_keyspace = True
+    
+
+stats_db_connection = None
+
+# FIXME: Should ideally create the column families on demand as the data
+# is added, so the different target types don't need to be predefined here.
+# Probably not a big problem for right now, though.
+COLUMN_FAMILY_INFO_LIST = (
+    {'name': TARGET_INDEX_NAME,
+     'column_type': 'Super',
+     'comparator_type': 'UTF8Type',
+     'subcomparator_type': 'UTF8Type'},
+    {'name': STATS_TYPE_INDEX_NAME,
+     'column_type': 'Super',
+     'comparator_type': 'UTF8Type',
+     'subcomparator_type': 'UTF8Type'},
+    {'name': CONTROLLER_STATS_NAME + STATS_COLUMN_FAMILY_NAME_SUFFIX,
+     'comparator_type': 'UTF8Type'},
+    {'name': SWITCH_STATS_NAME + STATS_COLUMN_FAMILY_NAME_SUFFIX,
+     'comparator_type': 'UTF8Type'},
+    {'name': PORT_STATS_NAME + STATS_COLUMN_FAMILY_NAME_SUFFIX,
+     'comparator_type': 'UTF8Type'},
+    {'name': EVENTS_COLUMN_FAMILY_NAME,
+     'column_type': 'Super',
+     'comparator_type': 'UTF8Type',
+     'subcomparator_type': 'UTF8Type'},
+)
+        
+
+def init_stats_db_connection(host, port, keyspace, user, password,
+                             replication_factor, column_family_def_default_settings):
+    global stats_db_connection
+    if not stats_db_connection:
+        if use_test_keyspace:
+            keyspace = "test_" + keyspace
+            
+        try:
+            stats_db_connection = CassandraConnection(host, port, keyspace, user, password)
+            stats_db_connection.connect()
+        except Exception:
+            stats_db_connection = None
+            raise StatsException("Error connecting to Cassandra daemon")
+        
+        if use_test_keyspace:
+            try:
+                stats_db_connection.get_client().system_drop_keyspace(keyspace)
+            except Exception:
+                pass
+            
+        try:
+            stats_db_connection.set_keyspace()
+            create_keyspace = False
+        except Exception:
+            create_keyspace = True
+        
+        if create_keyspace:
+            keyspace_def = KsDef(name=keyspace,
+                                 strategy_class='org.apache.cassandra.locator.SimpleStrategy',
+                                 replication_factor=replication_factor,
+                                 cf_defs=[])
+            try:
+                stats_db_connection.get_client().system_add_keyspace(keyspace_def)
+                stats_db_connection.set_keyspace()
+            except Exception, _e:
+                stats_db_connection = None
+                raise StatsException("Error creating stats keyspace")
+        
+        for column_family_info in COLUMN_FAMILY_INFO_LIST:
+            try:
+                column_family_def_settings = column_family_def_default_settings.copy()
+                column_family_def_settings.update(column_family_info)
+                column_family_def_settings['keyspace'] = keyspace
+                # pylint: disable=W0142
+                stats_db_connection.get_client().system_add_column_family(
+                    CfDef(**column_family_def_settings))
+            except InvalidRequestException, _e:
+                # Assume this is because the column family already exists.
+                # FIXME. Could check exception message for specific string
+                pass
+            except Exception, _e:
+                stats_db_connection = None
+                raise StatsCreateColumnFamilyException(column_family_info.get('name'))
+
+
+def get_stats_db_connection():
+    return stats_db_connection
+
+
+# The following function is mainly intended to be used by the unit tests. It lets
+# you clear out all of the data from the database. Note that since the stats DB
+# is not managed by the normal Django DB mechanism you don't get the automatic
+# DB flushing from the Django TestCase code, so it has to be done explicitly.
+# There's a StatsTestCase subclass of TestCase in the stats unit tests that
+# implements the tearDown method to call flush_stats_db after each test.
+def flush_stats_db():
+    if stats_db_connection is not None:
+        for column_family_info in COLUMN_FAMILY_INFO_LIST:
+            stats_db_connection.get_client().truncate(column_family_info['name'])
+
+def call_cassandra_with_reconnect(fn, *args, **kwargs):
+    try:
+        try:
+            results = fn(*args, **kwargs)
+        except TTransport.TTransportException:
+            stats_db_connection.reconnect()
+            results = fn(*args, **kwargs)
+    except TTransport.TTransportException, _e:
+        raise StatsDatabaseConnectionException()
+    except Exception, _e:
+        raise StatsDatabaseAccessException()
+
+    return results
+
+
+def get_stats_padded_column_part(column_part):
+    """
+    For the columns to be sorted correctly by time we need to pad with
+    leading zeroes up to the maximum range of the bucket
+    """
+    column_part = str(column_part)
+    leading_zeroes = ('0'*(STATS_PADDED_COLUMN_TIME_LENGTH-len(column_part)))
+    column_part = leading_zeroes + column_part
+    return column_part
+
+
+def split_stats_timestamp(timestamp):
+    key_part = timestamp / STATS_BUCKET_PERIOD
+    column_part = timestamp % STATS_BUCKET_PERIOD
+    return (key_part, column_part)
+
+
+def construct_stats_key(cluster, target_id, stats_type, timestamp_key_part):
+    """
+    Constructs the keys for the controller or switch stats.
+    For the controller stats the target_id is the controller node id.
+    For switch stats the target_id is the dpid of the switch.
+    """
+    return cluster + '|' + target_id + '|' + stats_type + '|' + str(timestamp_key_part)
+
+
+def append_stats_results(get_results, values, timestamp_key_part):
+    shifted_timestamp_key_part = int(timestamp_key_part) * STATS_BUCKET_PERIOD
+    for item in get_results:
+        timestamp_column_part = int(item.column.name)
+        value = item.column.value
+        timestamp = shifted_timestamp_key_part + timestamp_column_part
+        values.append((timestamp, value))
+
+
+def get_stats_slice_predicate(column_start, column_end):
+    if column_start != '':
+        column_start = get_stats_padded_column_part(column_start)
+    if column_end != '':
+        column_end = get_stats_padded_column_part(column_end)
+    slice_predicate = SlicePredicate(slice_range=SliceRange(
+        start=column_start, finish=column_end, count=1000000))
+    return slice_predicate
+
+
+def check_time_range(start_time, end_time):
+    if int(end_time) < int(start_time):
+        raise StatsInvalidStatsTimeRangeException(start_time, end_time)
+    
+    
+def check_valid_data_format(data_format):
+    if data_format != VALUE_DATA_FORMAT and data_format != RATE_DATA_FORMAT:
+        raise StatsInvalidDataFormatException(data_format)
+
+
+def get_window_range(raw_stats_values, index, window):
+
+    if window == 0:
+        return (index, index)
+    
+    # Get start index
+    timestamp = raw_stats_values[index][0]
+    start_timestamp = timestamp - (window / 2)
+    end_timestamp = timestamp + (window / 2)
+    
+    start_index = index
+    while start_index > 0:
+        next_timestamp = raw_stats_values[start_index - 1][0]
+        if next_timestamp < start_timestamp:
+            break
+        start_index -= 1
+    
+    end_index = index
+    while end_index < len(raw_stats_values) - 1:
+        next_timestamp = raw_stats_values[end_index + 1][0]
+        if next_timestamp > end_timestamp:
+            break
+        end_index += 1
+        
+    return (start_index, end_index)
+
+
+def convert_stat_string_to_value(stat_string):
+    try:
+        stat_value = int(stat_string)
+    except ValueError:
+        try:
+            stat_value = float(stat_string)
+        except ValueError:
+            stat_value = stat_string
+    return stat_value
+
+
+def get_rate_over_stats_values(stats_values):
+    
+    if len(stats_values) < 2:
+        return None
+    
+    start_stat = stats_values[0]
+    end_stat = stats_values[-1]
+    
+    timestamp_delta = end_stat[0] - start_stat[0]
+    # NOTE: In computing the value_delta here it's safe to assume floats
+    # rather than calling convert_stat_string_to_value because we're going
+    # to be converting to float anyway when we do the rate calculation later.
+    # So there's no point in trying to differentiate between int and float
+    # and rate doesn't make sense for any other type of stat data (e.g. string)
+    value_delta = float(end_stat[1]) - float(start_stat[1])
+    if timestamp_delta == 0:
+        rate = float('inf' if value_delta > 0  else '-inf')
+    else:
+        rate = value_delta / timestamp_delta
+    
+    return rate
+
+
+def get_rate_over_window(raw_stats_values, index, window):
+    if len(raw_stats_values) < 2:
+        return None
+    
+    if window == 0:
+        if index == 0:
+            start_index = 0
+            end_index = 1
+        else:
+            start_index = index - 1
+            end_index = index
+    else:
+        start_index, end_index = get_window_range(raw_stats_values, index, window)
+    
+    return get_rate_over_stats_values(raw_stats_values[start_index:end_index + 1])
+
+
+def get_average_over_stats_values(stats_values):
+    
+    total = 0
+    count = 0
+    for stat_value in stats_values:
+        # FIXME: Should we just always convert to float here?
+        # This would give a more accurate result for the average calculation
+        # but would mean that the data type is different for a
+        # zero vs. non-zero window size.
+        value = convert_stat_string_to_value(stat_value[1])
+        if type(value) not in (int,float):
+            raise StatsNonnumericValueException(value)
+        total += value
+        count += 1
+    
+    return (total / count) if count > 0 else None
+
+
+def get_average_value_over_window(raw_stats_values, index, window):
+    start_index, end_index = get_window_range(raw_stats_values, index, window)
+    stats_values = raw_stats_values[start_index:end_index + 1]
+    return get_average_over_stats_values(stats_values)
+
+
+def reverse_stats_data_generator(cluster, target_type, target_id, stats_type,
+                                 start_time=None, end_time=None,
+                                 chunk_interval=3600000):
+    if start_time is None:
+        start_time = int(time.time() * 1000)
+    if end_time is None:
+        # By default, don't go back past 1/1/2011. This was before we had stats support
+        # in the controller, so we shouldn't have any data earlier than that (except if
+        # the clock on the controller was set incorrectly).
+        end_time = int(time.mktime(datetime.datetime(2011,1,1).timetuple()) * 1000)
+    end_key_part, _end_column_part = split_stats_timestamp(end_time)
+    key_part, column_part = split_stats_timestamp(start_time)
+    column_family = target_type + STATS_COLUMN_FAMILY_NAME_SUFFIX
+    column_parent = ColumnParent(column_family)
+    # FIXME: Should add support for chunk_interval to be either iterable or a
+    # list/tuple to give a sequence of chunk intervals to use. The last available
+    # chunk interval from the list/tuple/iterator would then be used for any
+    # subsequent cassandra calls
+    #chunk_interval_iter = (chunk_interval if isinstance(chunk_interval, list) or
+    #   isinstance(chunk_interval, tuple) else [chunk_interval])
+    while key_part >= 0:
+        key = construct_stats_key(cluster, target_id, stats_type, key_part)
+        
+        while True:
+            column_start = column_part - chunk_interval
+            if column_start < 0:
+                column_start = 0
+            slice_predicate = get_stats_slice_predicate(column_start, column_part)
+            for attempt in (1,2):
+                try:
+                    get_results = stats_db_connection.get_client().get_slice(key,
+                        column_parent, slice_predicate, ConsistencyLevel.ONE)
+                    for item in reversed(get_results):
+                        timestamp = (key_part * STATS_BUCKET_PERIOD) + int(item.column.name)
+                        value = item.column.value
+                        yield (timestamp, value)
+                    break
+                except TTransport.TTransportException:
+                    # Only retry once, so if it's the second time through,
+                    # propagate the exception
+                    if attempt == 2:
+                        raise StatsDatabaseConnectionException()
+                    stats_db_connection.reconnect()
+                except Exception:
+                    raise StatsDatabaseAccessException()
+
+            column_part = column_start
+            if column_part == 0:
+                break
+        
+        if key_part == end_key_part:
+            break
+        key_part -= 1
+        column_part = STATS_BUCKET_PERIOD - 1
+
+
+def get_latest_stat_data(cluster, target_type, target_id, stats_type,
+                         window=0, data_format=VALUE_DATA_FORMAT):
+    
+    check_valid_data_format(data_format)
+    
+    minimum_data_points = 2 if data_format == RATE_DATA_FORMAT else 1
+    stats_data_window = []
+    latest_stat_timestamp = None
+    
+    start_time = int(time.time() * 1000)
+    # Limit how far back we'll look for the latest stat value.
+    # 86400000 is 1 day in ms
+    end_time = start_time - 86400000
+    for stat_data_point in reverse_stats_data_generator(cluster,
+            target_type, target_id, stats_type, start_time, end_time):
+        current_stat_timestamp = stat_data_point[0]
+        if latest_stat_timestamp is None:
+            latest_stat_timestamp = current_stat_timestamp
+        
+        # NOTE: For stats operations we treat the window for the rate or
+        # average calculation to be centered around the current timestamp.
+        # For the latest stat case there is no data after the current point.
+        # We could extend the window back further so that the current timestamp
+        # is the end of the window range instead of the middle, but then that
+        # would be inconsistent with the other cases, so instead we just go
+        # back to half the window size. I haven't been able to convince myself
+        # strongly one way or the other which is better (or how much it matters)
+        outside_window = (latest_stat_timestamp - current_stat_timestamp) > (window / 2)
+        if len(stats_data_window) >= minimum_data_points and outside_window:
+            break
+        
+        stats_data_window.insert(0, stat_data_point)
+    
+        if (window == 0) and (len(stats_data_window) >= minimum_data_points):
+            break
+        
+    stat_data_point = None
+    
+    if latest_stat_timestamp is not None:
+        if data_format == VALUE_DATA_FORMAT:
+            value = get_average_over_stats_values(stats_data_window)
+        else:
+            assert data_format == RATE_DATA_FORMAT, "Invalid data format"
+            value = get_rate_over_stats_values(stats_data_window)
+        if value is not None:
+            stat_data_point = (latest_stat_timestamp, value)
+
+    return stat_data_point
+
+
+def get_stats_data(cluster, target_type, target_id, stats_type,
+                   start_time, end_time, sample_interval=0, window=0,
+                   data_format=VALUE_DATA_FORMAT, limit=None):
+    
+    check_time_range(start_time, end_time)
+    check_valid_data_format(data_format)
+    # FIXME: Add validation of other arguments
+    
+    start_key_part, start_column_part = split_stats_timestamp(int(start_time))
+    end_key_part, end_column_part = split_stats_timestamp(int(end_time))
+    
+    raw_stats_values = []
+    column_family = target_type + STATS_COLUMN_FAMILY_NAME_SUFFIX
+    column_parent = ColumnParent(column_family)
+    
+    for key_part in range(start_key_part, end_key_part+1):
+        current_start = start_column_part if key_part == start_key_part else ''
+        current_end = end_column_part if key_part == end_key_part else ''
+        # FIXME: How big can the count be?
+        slice_predicate = get_stats_slice_predicate(current_start, current_end)
+        key = construct_stats_key(cluster, target_id, stats_type, key_part)
+        for attempt in (1,2):
+            try:
+                get_results = stats_db_connection.get_client().get_slice(key,
+                    column_parent, slice_predicate, ConsistencyLevel.ONE)
+                break
+            except TTransport.TTransportException:
+                # Only retry once, so if it's the second time through,
+                # propagate the exception
+                if attempt == 2:
+                    raise StatsDatabaseConnectionException()
+                stats_db_connection.reconnect()
+            except Exception:
+                raise StatsDatabaseAccessException()
+
+        append_stats_results(get_results, raw_stats_values, key_part)
+    
+        # FIXME: This logic to handle the limit argument isn't complete.
+        # It doesn't account for a non-zero window or dpwnsampling.
+        if (limit != None and sample_interval == 0 and window == 0 and
+            len(raw_stats_values) > limit):
+            raw_stats_values = raw_stats_values[:limit]
+            break
+    
+    stats_values = []
+    last_downsample_index = None
+    for i in range(0, len(raw_stats_values)):
+        # Handle downsampling
+        if sample_interval != 0:
+            downsample_index = raw_stats_values[i][0] / sample_interval
+            if downsample_index == last_downsample_index:
+                continue
+            last_downsample_index = downsample_index
+        
+        # Get the value based for the specified data format
+        if data_format == VALUE_DATA_FORMAT:
+            if sample_interval == 0:
+                value = convert_stat_string_to_value(raw_stats_values[i][1])
+            else:
+                value = get_average_value_over_window(raw_stats_values, i, window)
+        else:
+            assert data_format == RATE_DATA_FORMAT, "Invalid data format"
+            value = get_rate_over_window(raw_stats_values, i, window)
+            
+        if value is not None:
+            stats_values.append((raw_stats_values[i][0], value))
+    
+    return stats_values
+
+
+def delete_stats_data(cluster, target_type, target_id, stats_type,
+                      start_time, end_time):
+    
+    check_time_range(start_time, end_time)
+    # FIXME: Add validation of other arguments
+    
+    start_key_part, start_column_part = split_stats_timestamp(int(start_time))
+    end_key_part, end_column_part = split_stats_timestamp(int(end_time))
+    
+    column_family = target_type + STATS_COLUMN_FAMILY_NAME_SUFFIX
+    column_parent = ColumnParent(column_family)
+    # The Cassandra timestamps are in microseconds, not milliseconds,
+    # so we convert to microseconds. The Cassandra timestamp is derived
+    # from the stat timestamp (i.e. same time converted to microseconds),
+    # so we use the end_time + 1, since that's guaranteed to be greater
+    # than any of the timestamps for the sample points we're deleting.
+    timestamp = (int(end_time) * 1000) + 1
+    for key_part in range(start_key_part, end_key_part+1):
+        key = construct_stats_key(cluster, target_id, stats_type, key_part)
+        current_start = start_column_part if key_part == start_key_part else ''
+        current_end = end_column_part if key_part == end_key_part else ''
+        if current_start == '' and current_end == '':
+            call_cassandra_with_reconnect(stats_db_connection.get_client().remove,
+                key, ColumnPath(column_family=column_family), timestamp,
+                ConsistencyLevel.ONE)
+        else:
+            # grrr. Cassandra currently doesn't support doing deletions via a
+            # slice range (i.e. a column start and end). You need to give it a
+            # list of columns. So we do a get_slice with the slice range and then
+            # extract the individual column names from the result of that and
+            # build up the column list that we can use to delete the column
+            # using batch_mutate.
+            slice_predicate = get_stats_slice_predicate(current_start, current_end)
+            get_results = call_cassandra_with_reconnect(
+                stats_db_connection.get_client().get_slice,
+                key, column_parent, slice_predicate, ConsistencyLevel.ONE)
+            column_names = []
+            for item in get_results:
+                column_names.append(item.column.name)
+            
+            deletion = Deletion(timestamp=timestamp, predicate=SlicePredicate(column_names=column_names))
+            mutation_map = {key: {column_family: [Mutation(deletion=deletion)]}}
+            call_cassandra_with_reconnect(stats_db_connection.get_client().batch_mutate,
+                                          mutation_map, ConsistencyLevel.ONE)
+
+
+STATS_METADATA_VARIABLE_NAME = 'STATS_METADATA'
+
+stats_metadata = None
+
+def init_stats_metadata(_cluster):
+    """
+    Initialize the dictionary of stats metadata. Currently this is initialized
+    from a directory of metadata files that contain the metadata. Currently,
+    there is no differentiation in the stats types that are supported across
+    clusters, so we ignore the cluster argument and we just maintain a
+    global map of stat type metadata.
+    """
+    global stats_metadata
+    if not stats_metadata:
+        stats_metadata = {}
+        for module_name in settings.STATS_METADATA_MODULES:
+            metadata_module = __import__(module_name,
+                fromlist=[STATS_METADATA_VARIABLE_NAME])
+            if not metadata_module:
+                # FIXME: log error
+                continue
+            
+            if STATS_METADATA_VARIABLE_NAME not in dir(metadata_module):
+                # FIXME: log error
+                continue
+            
+            metadata_list = getattr(metadata_module, STATS_METADATA_VARIABLE_NAME)
+            
+            if type(metadata_list) is dict:
+                metadata_list = [metadata_list]
+
+            if type(metadata_list) is not list and type(metadata_list) is not tuple:
+                raise StatsInvalidStatsMetadataException(module_name)
+            
+            for metadata in metadata_list:
+                if type(metadata) is not dict:
+                    raise StatsInvalidStatsMetadataException(module_name)
+                    
+                name = metadata.get('name')
+                if not name:
+                    raise StatsInvalidStatsMetadataException(module_name)
+                name = str(name)
+                
+                # Auto-set the verbose_name to the name if it's not set explicitly
+                verbose_name = metadata.get('verbose_name')
+                if not verbose_name:
+                    metadata['verbose_name'] = name
+                    
+                # FIXME: Validate other contents of metadata.
+                # e.g. flag name conflicts between files.
+                
+                stats_metadata[name] = metadata
+                
+def get_stats_metadata(cluster, stats_type=None):
+    init_stats_metadata(cluster)
+    # If no stat_type is specified return the entire dictionary of stat types
+    metadata = stats_metadata.get(stats_type) if stats_type else stats_metadata
+    if metadata is None:
+        raise StatsInvalidStatsTypeException(stats_type)
+    return metadata
+
+
+STATS_INDEX_ATTRIBUTE_TYPES = {
+    'last-updated': int
+}
+def stats_type_slice_to_index_data(stats_type_slice):
+    index_data = {}
+    for super_column in stats_type_slice:
+        name = super_column.super_column.name
+        column_list = super_column.super_column.columns
+        if name == 'base':
+            insert_map = index_data
+        elif name.startswith('param:'):
+            colon_index = name.find(':')
+            parameter_name = name[colon_index+1:]
+            parameter_map = index_data.get('parameters')
+            if not parameter_map:
+                parameter_map = {}
+                index_data['parameters'] = parameter_map
+            insert_map = {}
+            parameter_map[parameter_name] = insert_map
+        else:
+            raise StatsInternalException('Invalid stats type index name: ' + str(name))
+        
+        for column in column_list:
+            value = column.value
+            attribute_type = STATS_INDEX_ATTRIBUTE_TYPES.get(column.name)
+            if attribute_type is not None:
+                value = attribute_type(value)
+            insert_map[column.name] = value
+    
+    return index_data
+
+
+def get_stats_type_index(cluster, target_type, target_id, stats_type=None):
+    column_parent = ColumnParent(STATS_TYPE_INDEX_NAME)
+    slice_predicate = SlicePredicate(slice_range=SliceRange(
+        start='', finish='', count=1000000))
+    key_prefix = cluster + ':' + target_type + ':' + target_id
+    if stats_type is None:
+        key_range = KeyRange(start_key=key_prefix+':', end_key=key_prefix+';', count=100000)
+        key_slice_list = call_cassandra_with_reconnect(
+            stats_db_connection.get_client().get_range_slices,
+            column_parent, slice_predicate, key_range, ConsistencyLevel.ONE)
+        stats_index_data = {}
+        for key_slice in key_slice_list:
+            key = key_slice.key
+            colon_index = key.rfind(':')
+            if colon_index < 0:
+                raise StatsInternalException('Invalid stats type index key: ' + str(key))
+            stats_type = key[colon_index+1:]
+            stats_index_data[stats_type] = stats_type_slice_to_index_data(key_slice.columns)
+    else:
+        key = key_prefix + ':' + stats_type
+        stats_type_slice = call_cassandra_with_reconnect(
+            stats_db_connection.get_client().get_slice, key, column_parent,
+            slice_predicate, ConsistencyLevel.ONE)
+        stats_index_data = stats_type_slice_to_index_data(stats_type_slice)
+        
+    return stats_index_data
+
+
+def get_stats_target_types(cluster):
+    column_parent = ColumnParent(TARGET_INDEX_NAME)
+    slice_predicate = SlicePredicate(column_names=[])
+    key_range = KeyRange(start_key=cluster+':', end_key=cluster+';', count=100000)
+    key_slice_list = call_cassandra_with_reconnect(
+        stats_db_connection.get_client().get_range_slices,
+        column_parent, slice_predicate, key_range, ConsistencyLevel.ONE)
+    
+    target_types = {}
+    for key_slice in key_slice_list:
+        target_type = key_slice.key[len(cluster)+1:]
+        
+        target_types[target_type] = {}
+    
+    return target_types
+
+
+STATS_TARGET_ATTRIBUTE_TYPES = {
+    'last-updated': int
+}
+
+def get_stats_targets(cluster, target_type):
+    key = cluster + ':' + target_type
+    column_parent = ColumnParent(TARGET_INDEX_NAME)
+    slice_predicate = SlicePredicate(slice_range=SliceRange(
+        start='', finish='', count=1000000))
+    super_column_list = call_cassandra_with_reconnect(
+        stats_db_connection.get_client().get_slice, key, column_parent,
+        slice_predicate, ConsistencyLevel.ONE)
+    target_list = {}
+    for item in super_column_list:
+        target = {}
+        for column in item.super_column.columns:
+            value = column.value
+            attribute_type = STATS_TARGET_ATTRIBUTE_TYPES.get(column.name)
+            if attribute_type is not None:
+                value = attribute_type(value)
+            target[column.name] = value
+        target_list[item.super_column.name] = target
+        
+    return target_list
+
+
+# FIXME: Should update the code below to use these constants
+# instead of string literals
+LAST_UPDATED_ATTRIBUTE_NAME = 'last-updated'
+CONTROLLER_ATTRIBUTE_NAME = 'controller'
+BASE_SUPER_COLUMN_NAME = 'base'
+PARAMETERS_SUPER_COLUMN_NAME = 'parameters'
+PARAM_SUPER_COLUMN_NAME_PREFIX = 'param:'
+
+def append_attributes_to_mutation_list(attributes, supercolumn_name, mutation_list):
+    column_list = []
+    for name, info in attributes.iteritems():
+        timestamp, value = info
+        column = Column(name=name, value=str(value), timestamp=timestamp*1000)
+        column_list.append(column)
+    mutation = Mutation(column_or_supercolumn=ColumnOrSuperColumn(
+        super_column=SuperColumn(name=supercolumn_name, columns=column_list)))
+    mutation_list.append(mutation)
+
+
+def add_stat_type_index_info_to_mutation_map(cluster, target_type,
+        stats_type_index, mutation_map):
+    for key, stats_type_info in stats_type_index.iteritems():
+        separator_index = key.find(':')
+        assert separator_index >= 0
+        base_stat_type_name = key[:separator_index]
+        target_id = key[separator_index + 1:]
+        stats_type_base_attributes, stats_type_params = stats_type_info
+        mutation_list = []
+        append_attributes_to_mutation_list(stats_type_base_attributes,
+            'base', mutation_list)
+        for name, attributes in stats_type_params.iteritems():
+            append_attributes_to_mutation_list(attributes,
+                'param:' + name, mutation_list)
+        mutation_key = cluster + ':' + target_type + ':' + target_id + ':' + base_stat_type_name
+        mutation_map[mutation_key] = {STATS_TYPE_INDEX_NAME: mutation_list}
+
+
+def add_target_id_list_to_mutation_map(cluster, target_type,
+                                       target_id_list, mutation_map):
+    mutation_list = []
+    for target_id, attributes in target_id_list:
+        append_attributes_to_mutation_list(attributes, target_id, mutation_list)
+    key = cluster + ':' + target_type
+    mutation_map[key] = {TARGET_INDEX_NAME: mutation_list}
+
+
+def _put_stats_data(cluster, target_type, stats_data):
+    try:
+        controller_id = get_local_controller_id()
+        mutation_map = {}
+        target_id_list = []
+        stats_type_index = {}
+        column_family = target_type + STATS_COLUMN_FAMILY_NAME_SUFFIX
+        for (target_id, target_id_stats) in stats_data.iteritems():
+            # Map 'localhost' controller to the actual ID for the local controller
+            # FIXME: Eventually we should fix up the other components (e.g. statd)
+            # that invoke this REST API to not use localhost and instead use the
+            # REST API to obtain the real ID for the local controller, but for now
+            # this works to ensure we're not using localhost in any of the data we
+            # store in the DB (unless, of course, the uuid version of the controller
+            # ID hasn't been written to the boot-config file, in which case it will
+            # default to the old localhost value).
+            if target_type == 'controller' and target_id == 'localhost':
+                target_id = controller_id
+            latest_id_timestamp = None
+            for (stats_type, stats_data_array) in target_id_stats.iteritems():
+                # Check if it's a parameterized type and extract the base
+                # stat type and parameter name.
+                parameter_separator = stats_type.find('__')
+                if parameter_separator >= 0:
+                    stats_type_base = stats_type[:parameter_separator]
+                    stats_type_parameter = stats_type[parameter_separator+2:]
+                else:
+                    stats_type_base = stats_type
+                    stats_type_parameter = None
+                
+                latest_stat_type_timestamp = None
+                
+                # Add the stats values to the mutation map
+                for stats_value in stats_data_array:
+                    timestamp = int(stats_value['timestamp'])
+                    if latest_stat_type_timestamp is None or timestamp > latest_stat_type_timestamp:
+                        latest_stat_type_timestamp = timestamp
+                    if latest_id_timestamp is None or timestamp > latest_id_timestamp:
+                        latest_id_timestamp = timestamp
+                    value = stats_value['value']
+                    timestamp_key_part, timestamp_column_part = split_stats_timestamp(timestamp)
+                    key = construct_stats_key(cluster, target_id, stats_type, timestamp_key_part)
+                    key_entry = mutation_map.get(key)
+                    if not key_entry:
+                        mutation_list = []
+                        mutation_map[key] = {column_family: mutation_list}
+                    else:
+                        mutation_list = key_entry[column_family]
+                    
+                    # Note: convert the Cassandra timestamp value to microseconds to
+                    # be consistent with standard Cassandra timestamp format.
+                    mutation = Mutation(column_or_supercolumn=ColumnOrSuperColumn(
+                        column=Column(name=get_stats_padded_column_part(timestamp_column_part),
+                        value=str(value), timestamp=timestamp*1000)))
+                    mutation_list.append(mutation)
+                
+                # Update the stat type index info.
+                # There can be multiple parameterized types for each base stats type,
+                # so we need to be careful about checking for existing data for
+                # the index_entry. Because of the dictionary nature of the put data
+                # and the way this is serialized into a Python dictionary, though,
+                # we are guaranteed that there won't be multiple entries for a 
+                # specific parameters stats type or the base stats type, so we don't
+                # need to handle duplicates for those.
+                if latest_stat_type_timestamp is not None:
+                    stats_type_index_key = stats_type_base + ':' + target_id
+                    stats_type_info = stats_type_index.get(stats_type_index_key)
+                    if not stats_type_info:
+                        # This is a tuple of two dictionaries: the attributes for
+                        # the base stat type and a dictionary of the parameterized
+                        # types that have been seen for that stat type. The
+                        # parameterized type dictionary is keyed by the name of
+                        # the parameterized type and the value is the associated
+                        # attribute dictionary.
+                        stats_type_info = ({},{})
+                        stats_type_index[stats_type_index_key] = stats_type_info
+                    stats_type_base_attributes, stats_type_params = stats_type_info
+                    if stats_type_parameter is None:
+                        attributes = stats_type_base_attributes
+                    else:
+                        attributes = stats_type_params.get(stats_type_parameter)
+                        if attributes is None:
+                            attributes = {}
+                            stats_type_params[stats_type_parameter] = attributes
+                    last_updated_entry = attributes.get('last-updated')
+                    if last_updated_entry is None or latest_stat_type_timestamp > last_updated_entry[0]:
+                        attributes['last-updated'] = (latest_stat_type_timestamp, latest_stat_type_timestamp)
+                    
+            # Update the target index
+            if latest_id_timestamp is not None:
+                # FIXME: Always set the controller attributes for now.
+                # This could/should be optimized to not set this for stats
+                # whose target type is 'controller' since those will
+                # always be coming from the same controller (i.e. itself).
+                # But that change requires some changes (albeit minor) to
+                # syncd to work correctly which I don't want to mess with
+                # right now.
+                #attributes = {'last-updated': (latest_id_timestamp, latest_id_timestamp)}
+                #if target_type != 'controller':
+                #    attributes['controller'] = controller_id
+                attributes = {'last-updated': (latest_id_timestamp, latest_id_timestamp),
+                              'controller': (latest_id_timestamp, controller_id)}
+                target_id_list.append((target_id, attributes))
+    except Exception, _e:
+        raise StatsInvalidStatsDataException()
+    
+    add_stat_type_index_info_to_mutation_map(cluster, target_type, stats_type_index, mutation_map)
+    add_target_id_list_to_mutation_map(cluster, target_type, target_id_list, mutation_map)
+    
+    call_cassandra_with_reconnect(stats_db_connection.get_client().batch_mutate,
+                                  mutation_map, ConsistencyLevel.ONE)
+
+
+def put_stats_data(cluster, stats_data):
+    for target_type, target_stats_data in stats_data.items():
+        if target_type.endswith(STATS_TARGET_TYPE_PUT_DATA_SUFFIX):
+            # Strip off the '-stats' suffix
+            target_type = target_type[:-len(STATS_TARGET_TYPE_PUT_DATA_SUFFIX)]
+        _put_stats_data(cluster, target_type, target_stats_data)
+        
+
+def get_events_padded_column_part(column_part):
+    """
+    For the columns to be sorted correctly by time we need to pad with
+    leading zeroes up to the maximum range of the bucket
+    """
+    column_part = str(column_part)
+    leading_zeroes = ('0'*(EVENTS_PADDED_COLUMN_TIME_LENGTH-len(column_part)))
+    column_part = leading_zeroes + column_part
+    return column_part
+
+
+def split_events_timestamp(timestamp):
+    key_part = timestamp / EVENTS_BUCKET_PERIOD
+    column_part = timestamp % EVENTS_BUCKET_PERIOD
+    return (key_part, column_part)
+
+
+def construct_log_events_key(cluster, node_id, timestamp_key_part):
+    return cluster + '|' + node_id + '|' + str(timestamp_key_part)
+
+
+def get_events_slice_predicate(column_start, column_end):
+    if column_start != '':
+        column_start = get_events_padded_column_part(column_start)
+    if column_end != '':
+        # For the final key in the range of keys we want all of the
+        # supercolumns whose name starts with end_column_part.
+        # If the event has includes a pk tag then the format of the
+        # supercolumn name is <timestamp-part>:<pk-tag>.
+        # Otherwise it's just the <timestamp-part>. To get both of these
+        # cases we set the column end value to be the <timestamp-part>
+        # suffixed with ';' (which has an ordinal value 1 greater than
+        # ':'. So this will get all of the events with the given column
+        # end regardless of whether or not they include the pk tag.
+        column_end = get_events_padded_column_part(column_end) + ';'
+    slice_predicate = SlicePredicate(slice_range=SliceRange(
+        start=column_start, finish=column_end, count=1000000))
+    return slice_predicate
+
+
+def append_log_events_results(event_results, event_list, timestamp_key_part, include_pk_tag=False):
+    shifted_timestamp_key_part = int(timestamp_key_part) * EVENTS_BUCKET_PERIOD
+    for item in event_results:
+        event = {}
+        super_column_name = item.super_column.name
+        colon_index = super_column_name.find(":")
+        if colon_index >= 0:
+            if include_pk_tag:
+                pk_tag = super_column_name[colon_index:]
+                event['pk-tag'] = pk_tag
+            timestamp_column_part = super_column_name[:colon_index]
+        else:
+            timestamp_column_part = super_column_name
+        timestamp = shifted_timestamp_key_part + int(timestamp_column_part)
+        event['timestamp'] = timestamp
+        for column in item.super_column.columns:
+            event[column.name] = column.value
+        event_list.append(event)
+
+     
+def get_log_event_data(cluster, node_id, start_time, end_time, include_pk_tag=False):
+    # FIXME: Add some validation of arguments
+    start_key_part, start_column_part = split_events_timestamp(int(start_time))
+    end_key_part, end_column_part = split_events_timestamp(int(end_time))
+    
+    event_list = []
+    column_parent = ColumnParent(column_family=EVENTS_COLUMN_FAMILY_NAME)
+    for key_part in range(start_key_part, end_key_part+1):
+        current_start = start_column_part if key_part == start_key_part else ''
+        current_end = end_column_part if key_part == end_key_part else ''
+        # FIXME: How big can the count be?
+        slice_predicate = get_events_slice_predicate(current_start, current_end)
+        key = construct_log_events_key(cluster, node_id, key_part)
+        for attempt in (1,2):
+            try:
+                results = stats_db_connection.get_client().get_slice(key,
+                    column_parent, slice_predicate, ConsistencyLevel.ONE)
+                break
+            except TTransport.TTransportException:
+                # Only retry once, so if it's the second time through,
+                # propagate the exception
+                if attempt == 2:
+                    raise StatsDatabaseConnectionException()
+                stats_db_connection.reconnect()
+            except Exception:
+                raise StatsDatabaseAccessException()
+        append_log_events_results(results, event_list, key_part, include_pk_tag)
+    
+    return event_list
+
+
+def put_log_event_data(cluster, log_events_data):
+    try:
+        mutation_map = {}
+        for (node_id, node_events) in log_events_data.iteritems():
+            for event in node_events:
+                timestamp = event['timestamp']
+                pk_tag = event.get('pk-tag')
+                # If the entry in the put data does not specify a tag, then generate a random one.
+                # This is so that we can have multiple events with the same timestamp.
+                # FIXME: Is there something better we can do here?
+                if not pk_tag:
+                    pk_tag = random.randint(0,10000000000)
+                timestamp = int(timestamp)
+                timestamp_key_part, timestamp_column_part = split_events_timestamp(timestamp)
+                key = construct_log_events_key(cluster, node_id, timestamp_key_part)
+                key_entry = mutation_map.get(key)
+                if not key_entry:
+                    mutation_list = []
+                    mutation_map[key] = {EVENTS_COLUMN_FAMILY_NAME: mutation_list}
+                else:
+                    mutation_list = key_entry[EVENTS_COLUMN_FAMILY_NAME]
+                supercolumn_name = get_events_padded_column_part(timestamp_column_part)
+                if pk_tag is not None:
+                    supercolumn_name += (':' + str(pk_tag))
+                # Build the list of columns in the supercolumn
+                column_list = []
+                for (name, value) in event.iteritems():
+                    if name != 'timestamp':
+                        column_list.append(Column(name=name, value=str(value),
+                                                  timestamp=timestamp*1000))
+                mutation = Mutation(column_or_supercolumn=ColumnOrSuperColumn(
+                                    super_column=SuperColumn(name=supercolumn_name,
+                                    columns=column_list)))
+                mutation_list.append(mutation)
+    except Exception:
+        raise StatsInvalidStatsDataException()
+    
+    call_cassandra_with_reconnect(stats_db_connection.get_client().batch_mutate,
+                                  mutation_map, ConsistencyLevel.ONE)
+
+def delete_log_event_data(cluster, node_id, start_time, end_time):
+    start_key_part, start_column_part = split_events_timestamp(int(start_time))
+    end_key_part, end_column_part = split_events_timestamp(int(end_time))
+    # The Cassandra timestamps are in microseconds, not milliseconds,
+    # so we convert to microseconds. The Cassandra timestamp is derived
+    # from the event timestamp (i.e. same time converted to microseconds),
+    # so we use the end_time + 1, since that's guaranteed to be greater
+    # than any of the timestamps for the sample points we're deleting.
+    timestamp = (int(end_time) * 1000) + 1
+    column_path = ColumnPath(column_family=EVENTS_COLUMN_FAMILY_NAME)
+    column_parent = ColumnParent(column_family=EVENTS_COLUMN_FAMILY_NAME)
+    for key_part in range(start_key_part, end_key_part+1):
+        key = construct_log_events_key(cluster, node_id, key_part)
+        current_start = start_column_part if key_part == start_key_part else ''
+        current_end = end_column_part if key_part == end_key_part else ''
+        if current_start == '' and current_end == '':
+            call_cassandra_with_reconnect(stats_db_connection.get_client().remove,
+                key, column_path, timestamp, ConsistencyLevel.ONE)
+        else:
+            # grrr. Cassandra currently doesn't support doing deletions via a
+            # slice range (i.e. a column start and end). You need to give it a
+            # list of columns. So we do a get_slice with the slice range and then
+            # extract the individual column names from the result of that and
+            # build up the column list that we can use to delete the column
+            # using batch_mutate.
+            slice_predicate = get_events_slice_predicate(current_start, current_end)
+            get_results = call_cassandra_with_reconnect(
+                stats_db_connection.get_client().get_slice,
+                key, column_parent, slice_predicate, ConsistencyLevel.ONE)
+            column_names = []
+            for item in get_results:
+                column_names.append(item.super_column.name)
+            
+            deletion = Deletion(timestamp=timestamp, predicate=SlicePredicate(column_names=column_names))
+            mutation_map = {key: {EVENTS_COLUMN_FAMILY_NAME: [Mutation(deletion=deletion)]}}
+            call_cassandra_with_reconnect(stats_db_connection.get_client().batch_mutate,
+                                          mutation_map, ConsistencyLevel.ONE)
+
+
+def get_closest_sample_interval(requested_sample_interval):
+    for i in range(0, len(DOWNSAMPLE_INTERVALS)):
+        if DOWNSAMPLE_INTERVALS[i] > requested_sample_interval:
+            if i == 0:
+                return requested_sample_interval
+            downsample_interval = DOWNSAMPLE_INTERVALS[i - 1]
+            break
+    else:
+        downsample_interval = DOWNSAMPLE_INTERVALS[-1]
+    # Return the closest multiple of the downsampled interval
+    return downsample_interval * (requested_sample_interval // downsample_interval)
+
+
+def get_closest_window_interval(requested_window):
+    for i in range(0, len(WINDOW_INTERVALS)):
+        if WINDOW_INTERVALS[i] > requested_window:
+            return WINDOW_INTERVALS[i - 1] if i > 0 else 0
+    return WINDOW_INTERVALS[-1]
diff --git a/sdncon/stats/models.py b/sdncon/stats/models.py
new file mode 100755
index 0000000..a493475
--- /dev/null
+++ b/sdncon/stats/models.py
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.db import models
+"""
+class StatdConfig(models.Model):
+    stat_type = models.CharField(
+        primary_key=True,
+        verbose_name='Stat Type',
+        max_length=64)
+    
+    sampling_period = models.PositiveIntegerField(
+        verbose_name='Sampling Period',
+        default=15)
+    
+    reporting_period = models.PositiveIntegerField(
+        verbose_name='Reporting Period',
+        default=60)
+    
+    class Rest:
+        NAME = 'statd-config'
+        FIELD_INFO = (
+            {'name': 'stat_type', 'rest_name': 'stat-type'},
+            {'name': 'sampling_period', 'rest_name': 'sampling-period'},
+            {'name': 'reporting_period', 'rest_name': 'reporting-period'},
+            )
+"""
\ No newline at end of file
diff --git a/sdncon/stats/statsFiller.py b/sdncon/stats/statsFiller.py
new file mode 100755
index 0000000..89f202f
--- /dev/null
+++ b/sdncon/stats/statsFiller.py
@@ -0,0 +1,484 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+import json
+import logging
+import sys
+import time
+import random
+import urllib2
+import re
+import urllib
+from optparse import OptionParser, OptionGroup
+
+DEFAULT_CONTROLLER_ID = 'localhost'
+
+DEFAULT_BATCH = 5
+DEFAULT_SAMPLING_INTERVAL = 5
+
+STATS_CPU = 'cpu'
+STATS_MEM = 'mem'
+STATS_SWAP = 'swap'
+STATS_OF = 'of'
+STATS_LOG = 'log'
+
+STATS = [STATS_CPU, STATS_MEM, STATS_SWAP, STATS_OF, STATS_LOG]
+
+BASE_TIME = 1297278987000
+SECONDS_CONVERT = 1000
+MINUTES_CONVERT = 60 * SECONDS_CONVERT
+HOURS_CONVERT = 60 * MINUTES_CONVERT
+DAYS_CONVERT = 24 * HOURS_CONVERT
+
+numSamples = 0
+samplingInterval = 0
+batchSize = 0
+statsTypes = [] 
+numSwitches = 0
+switchIDs = []
+seed = 0
+controller = ''
+logger = 0
+debugLevel = logging.INFO
+logfile = 'filler.log'
+
+def initLogger():
+    # create a statFiller logger
+    logger = logging.getLogger("filler")
+    logger.setLevel(debugLevel)
+
+    formatter = logging.Formatter("%(asctime)s [%(name)s] %(levelname)s %(message)s")
+    # Add a file handler
+    rf_handler = logging.FileHandler(logfile)
+    rf_handler.setFormatter(formatter)
+    logger.addHandler(rf_handler)
+
+    # Add a console handler
+    co_handler = logging.StreamHandler()
+    co_handler.setFormatter(formatter)
+    co_handler.setLevel(logging.WARNING)
+    logger.addHandler(co_handler)
+
+    return logger
+
+def intToDpid(intValue):
+    import string
+    ret = []
+    if intValue > (2**128-1):
+        intValue = 2**128-1
+    for i in range(16):
+        mask = 0x0f<<(i*4)
+        tmp = (intValue&mask)>>(i*4)
+        ret.insert(0,string.hexdigits[tmp])
+        if i != 15 and i%2 == 1:
+            ret.insert(0, ':')
+
+    return ''.join(ret)
+
+def getRandomInc():
+    """ 
+    Randomly create an integer from 1 to 100
+    """
+    return random.randint(1,100)
+
+def getRandomInt(max):
+    """ 
+    Randomly create an integer from 1 to max
+    """
+    if max <= 1:
+        return 1
+    else:
+        return random.randint(1,max)
+
+def getRandomPercentage(max):
+    """ 
+    Randomly create a two-decimal percentage
+    """
+    percentMax = int(max * 100)
+    if percentMax < 2:
+        return 0.01
+    else:
+        try:
+            v = float(random.randint(1, percentMax))
+            return v/100
+        except ValueError as e:
+            logger.error ("error: %s, percentMax=%d"%(e, percentMax))
+            return 0.01
+
+class StatsFiller():
+  
+    statsData = {}
+    logData = {}
+    
+    of_packetin = 0 
+    of_flowmod = 0 
+    of_activeflow = 0 
+    hostID = 'localhost'
+
+    def __init__(self, numSamples, samplingInterval, batchSize, switchIDs, statsTypes, hostID, cluster, components, seed, logger):
+        self.numSamples = numSamples
+        self.samplingInterval = samplingInterval
+        self.batchSize = batchSize
+        self.switchIDs = switchIDs
+        self.statsTypes = statsTypes
+        self.controllerID = hostID
+        self.cluster = cluster
+        self.components = components
+        self.seed = seed
+        self.logger = logger
+
+    def repr(self):
+        return str(self.statsData)
+ 
+    def initStatsData(self):
+        if STATS_CPU in self.statsTypes or STATS_MEM in self.statsTypes or STATS_SWAP in self.statsTypes:
+            self.statsData['controller-stats'] = {}
+            self.statsData['controller-stats'][self.hostID] = {}
+
+            if STATS_CPU in self.statsTypes: 
+                self.statsData['controller-stats'][self.hostID]['cpu-idle'] = []
+                self.statsData['controller-stats'][self.hostID]['cpu-nice'] = []
+                self.statsData['controller-stats'][self.hostID]['cpu-user'] = []
+                self.statsData['controller-stats'][self.hostID]['cpu-system'] = []
+            if  STATS_MEM in self.statsTypes:
+                self.statsData['controller-stats'][self.hostID]['mem-used'] = []
+                self.statsData['controller-stats'][self.hostID]['mem-free'] = []
+            if  STATS_SWAP in self.statsTypes:
+                self.statsData['controller-stats'][self.hostID]['swap-used'] = []
+        
+        if STATS_OF in self.statsTypes:
+            self.statsData['switch-stats'] = {}
+            for dpid in switchIDs:
+                self.statsData['switch-stats'][dpid] = {}
+
+            if STATS_OF in self.statsTypes: 
+                for dpid in switchIDs:
+                    self.statsData['switch-stats'][dpid]['OFPacketIn'] = []
+                    self.statsData['switch-stats'][dpid]['OFFlowMod'] = []
+                    self.statsData['switch-stats'][dpid]['OFActiveFlow'] = []
+ 
+        if STATS_LOG in self.statsTypes:
+            self.logData[self.hostID] = []
+            
+    def generate_a_sw_stat(self, timestamp, dpid, statsTypes, value):
+        sample = {'timestamp':timestamp, 'value':value}
+        self.statsData['switch-stats'][dpid][statsTypes].append(sample)
+
+    def generate_a_controller_stat(self, timestamp, statsTypes, value):
+        sample = {'timestamp':timestamp, 'value':value}
+        self.statsData['controller-stats'][self.hostID][statsTypes].append(sample)
+
+    def generate_log_event(self, timestamp, component, log_level, message):
+        event = {'timestamp':timestamp, 'component':component, 'log-level':log_level,'message':message}
+        self.logData[self.hostID].append(event)
+        
+    def generate_a_batch(self, startTime, batchSize):
+        for i in range(batchSize):
+            # Get the sample timestamp in ms
+            ts = int(startTime + i * self.samplingInterval)*1000
+            # controller stats
+            if STATS_CPU in self.statsTypes:
+                max = 100.00
+                v = getRandomPercentage(max)
+                self.generate_a_controller_stat(ts, 'cpu-idle', round(v, 2))
+                max -= v
+                v = getRandomPercentage(max)
+                self.generate_a_controller_stat(ts, 'cpu-nice', round(v, 2))
+                max -= v
+                v = getRandomPercentage(max)
+                self.generate_a_controller_stat(ts, 'cpu-user', round(v, 2))
+                max -= v
+                self.generate_a_controller_stat(ts, 'cpu-system', round(v, 2))
+            if  STATS_MEM in self.statsTypes:
+                max = getRandomInt(1000000000)
+                v = getRandomInt(max)
+                self.generate_a_controller_stat(ts, 'mem-used', v)
+                max -= v
+                self.generate_a_controller_stat(ts, 'mem-free', max)
+            if  STATS_SWAP in self.statsTypes:
+                max = getRandomInt(1000000000)
+                v = getRandomInt(max)
+                self.generate_a_controller_stat(ts, 'swap-used', v)
+                
+            # switch stats
+            if STATS_OF in self.statsTypes:
+                for dpid in self.switchIDs:
+                    #print "add stats for %s"%dpid
+                    self.of_packetin = getRandomInt(100) 
+                    self.generate_a_sw_stat(ts, dpid, 'OFPacketIn', self.of_packetin)
+                    self.of_flowmod = getRandomInt(100) 
+                    self.generate_a_sw_stat(ts, dpid, 'OFFlowMod', self.of_flowmod)
+                    self.of_activeflow = getRandomInt(100) 
+                    self.generate_a_sw_stat(ts, dpid, 'OFActiveFlow', self.of_activeflow)
+
+            if STATS_LOG in self.statsTypes:
+                for component in components:
+                    self.generate_log_event(ts, component, 'Error', 'Another log message')
+                    
+    def constructRestRrls(self):
+        """
+        Construct the REST URL for the given host/statsPath, including
+        the items in the query_params dictionary as URL-encoded query parameters
+        """
+        self.statsUrl = 'http://%s:8000/rest/v1/stats/data/%s'%(self.controllerID, self.cluster)
+        self.logUrl = 'http://%s:8000/rest/v1/events/data/%s'%(self.controllerID, self.cluster)
+
+    def printRestErrorInfo(self, e):
+        """
+        Extract the error information and print it.
+        This is mainly intended to demonstrate how to extract the
+        error info from the exception. It may or may not make sense
+        to print out this information, depending on the application.
+        """
+        # Extract the info from the exception
+        error_code = e.getcode()
+        response_text = e.read()
+        try:
+            # Print the error info
+            logger.error('HTTP error: code = %d, %s'%(error_code, response_text))
+
+            obj = json.loads(response_text)
+            error_type = obj.get('error_type')
+            description = obj.get('description')
+
+            # Print the error info
+            logger.error('HTTP error code = %d; error_type = %s; description = %s'%(error_code, str(error_type), description))
+
+            # Print the optional validation error info
+            model_error = obj.get('model_error')
+            if model_error:
+                logger.error('model_error = %s'%str(model_error))
+            field_errors = obj.get('field_errors')
+            if field_errors:
+                logger.error('field_errors = %s'%str(field_errors))
+        except ValueError as e:
+            logger.error(e)
+
+
+    def putRestData(self, url, obj):
+        """
+        Put the given object data to the given type/id/params at the given host.
+        If both the id and query_param_dict are empty, then a new item is created.
+        Otherwise, existing data items are updated with the object data.
+        """
+
+        logger.debug("URL: %s"%url)
+        logger.debug("Sending: %s"%obj)
+        request = urllib2.Request(url, obj, {'Content-Type':'application/json'})
+        request.get_method = lambda: 'PUT'
+        try:
+            response = urllib2.urlopen(request)
+            ret = response.read()
+            logger.debug("Got response: %s"%str(ret))
+            return ret
+        except urllib2.HTTPError as e:
+            logger.error("Got Exception: %s"%str(e))
+            self.printRestErrorInfo(e)
+
+
+    def postData(self):
+        """ 
+        Put the given object data to the given type/id/params at the given host.
+        """
+
+        self.constructRestRrls()
+
+        if self.statsData:
+            output = json.JSONEncoder().encode(self.statsData)
+            retMsg = self.putRestData(self.statsUrl, output)
+            logger.info("Put rest call for stats data returns: %s"%retMsg)
+        if self.logData:
+            output = json.JSONEncoder().encode(self.logData)
+            retMsg = self.putRestData(self.logUrl, output)
+            logger.info("Put rest call for log data returns: %s"%retMsg)
+            
+    def fill(self):
+        endTime = time.time()
+        startTime = endTime - self.numSamples * self.samplingInterval
+        remainingSamples = self.numSamples 
+        batchSize = 0
+        while remainingSamples > 0:
+            logger.info("starttime = %s(%d), endtime = %s(%d)"%(time.ctime(startTime),startTime,time.ctime(endTime),endTime))
+            self.initStatsData()
+            if remainingSamples < self.batchSize:
+                batchSize = remainingSamples
+            else:
+                batchSize = self.batchSize
+            remainingSamples -= batchSize
+            self.generate_a_batch(startTime, batchSize)
+            startTime += self.samplingInterval * batchSize
+            self.postData()
+            sys.stdout.write("%0.2f%%\r"%(float(self.numSamples-remainingSamples)*100/self.numSamples))
+
+def parseLogLevel(level):
+    if 'debug'.startswith(level):
+        return logging.DEBUG
+    elif 'info'.startswith(level):
+        return logging.INFO
+    elif 'warning'.startswith(level):
+        return logging.WARNING
+    elif 'error'.startswith(level):
+        return logging.ERROR
+    elif 'critical'.startswith(level):
+        return logging.CRITICAL
+    else:
+        return None
+
+def processOptions(options):
+    """
+    Process the command line arguments
+    """
+
+    global numSamples
+    global samplingInterval
+    global batchSize
+    global statsTypes
+    global numSwitches
+    global switchIDs
+    global seed
+    global controller
+    global cluster
+    global components
+    global debugLevel
+    global logfile
+
+    if options.numSamples:
+        numSamples = options.numSamples
+
+    if options.period:
+        m = re.search("([0-9]*)([A-Za-z]*)$", options.period)
+        (value, unit) = m.groups()
+        if value:
+            value = int(value)
+        if unit:
+            if 'minutes'.startswith(unit):
+                value = 60*value
+            elif 'hours'.startswith(unit):
+                value = 60*60*value
+            elif 'days'.startswith(unit):
+                value = 24*60*60*value
+            elif not 'seconds'.startswith(unit):
+                raise ValueError("Invalid period: %s"%options.period)
+        numSamples = value
+
+    if options.sampleInterval:
+        samplingInterval = options.sampleInterval
+    else:
+        samplingInterval = DEFAULT_SAMPLING_INTERVAL
+
+    numSamples /= samplingInterval
+    
+    if options.batchSize:
+        batchSize = options.batchSize
+    else:
+        batchSize = DEFAULT_BATCH
+
+    if options.numSwitches:
+        numSwitches = options.numSwitches
+
+    if options.statsTypes:
+        statsTypes = options.statsTypes.split(',')
+        for stat in statsTypes:
+            if stat not in STATS:
+                raise ValueError("Invalid stat: %s"%stat)
+
+    if options.seed:
+        seed = options.seed
+    else:
+        seed = random.random()
+
+    if options.controller:
+        controller = options.controller
+    else:
+        controller = 'localhost'
+
+    if options.cluster:
+        cluster = options.cluster
+    else:
+        cluster = 'default'
+
+    components = options.components.split(',')
+    
+    if options.debugLevel:
+        debugLevel = parseLogLevel(options.debugLevel)
+    else:
+        debugLevel = logging.INFO
+
+    if not debugLevel:
+        raise ValueError("Incorrect debug level, %s."%options.debugLevel)
+
+    if options.logfile:
+        logfile = options.logfile
+    else:
+        logfile = 'filler.log'
+
+
+    if len(statsTypes) == 0:
+        raise ValueError("statsTypes is required.")
+
+    if STATS_OF in statsTypes:
+        if numSwitches == 0:
+            raise ValueError("numSwitches must be nonzero to generate of stats.")
+        else:
+            for i in range(numSwitches):
+                switchIDs.append(intToDpid(i))
+
+    if numSamples == 0:
+        raise ValueError("numSamples or period is required")
+
+
+
+if __name__ == '__main__':
+    parser = OptionParser()
+    group = OptionGroup(parser, "Commonly Used Options")
+    group.add_option("-n", "--numSamples", dest="numSamples", type="long", help="Number of samples to be generated. Can NOT be used with timePeriod option.") 
+    group.add_option("-p", "--timePeriod", dest="period", help="The time period to fill the stats data. "
+                            "The format can be in seconds, minutes, hours, or days. e.g. 100s(econds), 15m(inutes), 2h(ours), 3d(ays). "
+                            "Can NOT be used with numSamples option.") 
+    group.add_option("-t", "--samplingInterval", dest="sampleInterval", type = "int", help="The sampling interval in seconds") 
+    group.add_option("-b", "--batchSize", dest="batchSize", type = "int", help="The number of samples for each rest put") 
+    group.add_option("-s", "--numSwitches", dest="numSwitches", type = "int", help="The number of switches for OF stats. The dpids start with "
+                                "00:00:00:00:00:00:00:01 and increment to the number of switches.") 
+    group.add_option("-m", "--statsTypes", dest="statsTypes", help="A comma separated statsTypes, Options are cpu, mem, swap, of, and log." 
+                            " e.g. cpu,mem")
+    group.add_option("-c", "--controller", dest="controller", help="The IP address of the controller") 
+    group.add_option("-u", "--cluster", dest="cluster", help="cluster ID")
+    group.add_option("-z", "--components", dest="components", default="sdnplatform,cassandra", help="A comma-separated list of component names for log events")
+    parser.add_option_group(group)
+
+    lc_group = OptionGroup(parser, "Less Commonly Used Options")
+    lc_group.add_option("-r", "--seed", dest="seed", type = "int", help="Same data can be recreated by setting the same seed for the randomizer") 
+    lc_group.add_option("-d", "--debugLevel", dest="debugLevel", help="Set the log level for logging: debug, info, warning, critical, error") 
+    lc_group.add_option("-f", "--logfile", dest="logfile", help="The logfile that keeps the logs. Default is filler.log")
+    parser.add_option_group(lc_group)
+
+    (options, args) = parser.parse_args()
+    if len(args) != 0:
+        parser.error("incorrect number of arguments: %s"%args)
+
+
+    try:
+        processOptions(options)
+        logger = initLogger()
+        logger.debug("numSample:%d, samplingInterval:%d, batchSize=%d, statsTypes=%s, numSwitches=%d switchIDs=%s seed=%f cluster=%s components=%s"%
+                    (numSamples, samplingInterval, batchSize, statsTypes, numSwitches, switchIDs, seed, cluster, components)) 
+    except ValueError as e:
+        print("Error: %s"%e)
+        sys.exit()
+
+    filler = StatsFiller(numSamples, samplingInterval, batchSize, switchIDs, statsTypes, controller, cluster, components, seed, logger)
+    filler.fill()
diff --git a/sdncon/stats/tests.py b/sdncon/stats/tests.py
new file mode 100755
index 0000000..f2c69e1
--- /dev/null
+++ b/sdncon/stats/tests.py
@@ -0,0 +1,394 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.test import TestCase, Client
+import urllib
+from django.utils import simplejson
+from .data import set_use_test_keyspace, flush_stats_db
+import time
+from sdncon.controller.config import get_local_controller_id
+
+def setUpModule():
+    set_use_test_keyspace()
+    
+def test_construct_rest_url(path, query_params=None):
+    url = '/rest/%s' % path
+    if query_params:
+        url += '?'
+        url += urllib.urlencode(query_params)
+    return url
+
+def test_get_rest_data(path, query_params=None):
+    url = test_construct_rest_url(path, query_params)
+    c = Client()
+    response = c.get(url)
+    return response
+
+def test_put_rest_data(obj, path, query_params=None):
+    url = test_construct_rest_url(path, query_params)
+    data = simplejson.dumps(obj)
+    c = Client()
+    response = c.put(url , data, 'application/json')
+    return response
+
+def test_delete_rest_data(path, query_params=None):
+    url = test_construct_rest_url(path, query_params)
+    c = Client()
+    response = c.delete(url)
+    return response
+
+BASE_TIME = 1297278987000
+SECONDS_CONVERT = 1000
+MINUTES_CONVERT = 60 * SECONDS_CONVERT
+HOURS_CONVERT = 60 * MINUTES_CONVERT
+DAYS_CONVERT = 24 * HOURS_CONVERT
+
+def make_timestamp(day, hour=0, minute=0, second=0, milliseconds=0):
+    timestamp = BASE_TIME + (day * DAYS_CONVERT) + (hour * HOURS_CONVERT) + \
+        (minute * MINUTES_CONVERT) + (second * SECONDS_CONVERT) + milliseconds
+    return timestamp
+
+class StatsTestCase(TestCase):
+    def tearDown(self):
+        flush_stats_db()
+        
+class BasicStatsTest(StatsTestCase):
+    
+    STATS_DATA = {
+        'controller-stats': {
+            '192.168.1.1': {
+                'cpu-system': [
+                    {'timestamp':make_timestamp(1,0),'value':1},
+                    {'timestamp':make_timestamp(1,1),'value':2},
+                    {'timestamp':make_timestamp(1,2),'value':3},
+                    {'timestamp':make_timestamp(1,3),'value':4},
+                    {'timestamp':make_timestamp(1,4),'value':5},
+                    {'timestamp':make_timestamp(2,1),'value':6},
+                    {'timestamp':make_timestamp(2,2),'value':7},
+                    {'timestamp':make_timestamp(3,5),'value':8},
+                    {'timestamp':make_timestamp(3,8),'value':9},
+                    {'timestamp':make_timestamp(4,10),'value':10},
+                    {'timestamp':make_timestamp(4,11),'value':11},
+                    {'timestamp':make_timestamp(10,11),'value':12},
+                ],
+                'cpu-idle': [
+                    {'timestamp':make_timestamp(1,1),'value':80},
+                    {'timestamp':make_timestamp(1,2),'value':83},
+                    {'timestamp':make_timestamp(1,3),'value':82},
+                    {'timestamp':make_timestamp(1,4),'value':79},
+                    {'timestamp':make_timestamp(1,5),'value':85},
+                ]
+            }
+        },
+        'switch-stats': {
+            '00:01:02:03:04:05': {
+                'flow-count': [
+                    {'timestamp':make_timestamp(1,0),'value':60},
+                    {'timestamp':make_timestamp(1,1),'value':88},
+                    {'timestamp':make_timestamp(1,2),'value':102},
+                ],
+                'packet-count': [
+                    {'timestamp':make_timestamp(1,0),'value':100},
+                    {'timestamp':make_timestamp(1,1),'value':120},
+                    {'timestamp':make_timestamp(1,2),'value':160},
+                ],
+                'packet-count__arp': [
+                    {'timestamp':make_timestamp(1,0),'value':20},
+                    {'timestamp':make_timestamp(1,3),'value':25},
+                ],
+                'packet-count__lldp': [
+                    {'timestamp':make_timestamp(1,0),'value':30},
+                    {'timestamp':make_timestamp(1,4),'value':15},
+                ]
+            }
+        }
+    }
+
+    def check_stats_results(self, returned_results, expected_results, message=None):
+        self.assertEqual(len(returned_results), len(expected_results), message)
+        for i in range(len(returned_results)):
+            expected_timestamp = expected_results[i]['timestamp']
+            returned_timestamp = returned_results[i][0]
+            expected_value = expected_results[i]['value']
+            returned_value = returned_results[i][1]
+            self.assertEqual(expected_timestamp, returned_timestamp, message)
+            self.assertEqual(expected_value, returned_value, message)
+    
+    def setUp(self):
+        response = test_put_rest_data(self.STATS_DATA, 'v1/stats/data/local')
+        self.assertEqual(response.status_code, 200)
+        
+    def test_get_stats(self):
+        # Get all of the cpu-system stat data
+        response = test_get_rest_data('v1/stats/data/local/controller/192.168.1.1/cpu-system', {'start-time':make_timestamp(1,0),'end-time':make_timestamp(10,11), 'sample-interval':0})
+        self.assertEqual(response.status_code, 200)
+        results = simplejson.loads(response.content)
+        self.check_stats_results(results, self.STATS_DATA['controller-stats']['192.168.1.1']['cpu-system'])
+        
+        # Get just one days data of the cpu-system stat
+        response = test_get_rest_data('v1/stats/data/local/controller/192.168.1.1/cpu-system', {'start-time':make_timestamp(1,0),'end-time':make_timestamp(1,4), 'sample-interval':0})
+        self.assertEqual(response.status_code, 200)
+        results = simplejson.loads(response.content)
+        self.check_stats_results(results, self.STATS_DATA['controller-stats']['192.168.1.1']['cpu-system'][:5])
+
+        # Get two day range for cpu-system
+        response = test_get_rest_data('v1/stats/data/local/controller/192.168.1.1/cpu-system', {'start-time':make_timestamp(1,2,10),'end-time':make_timestamp(2,2,20), 'sample-interval':0})
+        self.assertEqual(response.status_code, 200)
+        results = simplejson.loads(response.content)
+        self.check_stats_results(results, self.STATS_DATA['controller-stats']['192.168.1.1']['cpu-system'][3:7])
+        
+        # Get all of the flow-count switch stat data
+        response = test_get_rest_data('v1/stats/data/local/switch/00:01:02:03:04:05/flow-count', {'start-time':make_timestamp(1,0),'end-time':make_timestamp(2,0), 'sample-interval':0})
+        self.assertEqual(response.status_code, 200)
+        results = simplejson.loads(response.content)
+        self.check_stats_results(results, self.STATS_DATA['switch-stats']['00:01:02:03:04:05']['flow-count'])
+
+        # Get part of the packet-count switch stat data
+        response = test_get_rest_data('v1/stats/data/local/switch/00:01:02:03:04:05/packet-count', {'start-time':make_timestamp(1,0),'end-time':make_timestamp(1,1), 'sample-interval':0})
+        self.assertEqual(response.status_code, 200)
+        results = simplejson.loads(response.content)
+        self.check_stats_results(results, self.STATS_DATA['switch-stats']['00:01:02:03:04:05']['packet-count'][:2])
+
+    def test_delete_stats(self):
+        # Delete all but the first 2 and last 2 sample points
+        response = test_delete_rest_data('v1/stats/data/local/controller/192.168.1.1/cpu-system', {
+            'start-time': self.STATS_DATA['controller-stats']['192.168.1.1']['cpu-system'][2]['timestamp'],
+            'end-time':self.STATS_DATA['controller-stats']['192.168.1.1']['cpu-system'][-3]['timestamp']})
+        self.assertEquals(response.status_code, 200)
+
+        response = test_get_rest_data('v1/stats/data/local/controller/192.168.1.1/cpu-system', {'start-time':make_timestamp(1,0),'end-time':make_timestamp(10,11), 'sample-interval':0})
+        self.assertEqual(response.status_code, 200)
+        results = simplejson.loads(response.content)
+        self.check_stats_results(results, self.STATS_DATA['controller-stats']['192.168.1.1']['cpu-system'][:2] + self.STATS_DATA['controller-stats']['192.168.1.1']['cpu-system'][-2:])
+
+    def test_stats_target_types(self):
+        
+        local_controller_id = get_local_controller_id()
+        
+        # Check getting the list of all target types
+        response = test_get_rest_data('v1/stats/target/local/')
+        self.assertEqual(response.status_code, 200)
+        results = simplejson.loads(response.content)
+        self.assertEqual(len(results.keys()), 2)
+        self.assertTrue('controller' in results)
+        self.assertTrue('switch' in results)
+        
+        # Check getting the info for the controller target type
+        response = test_get_rest_data('v1/stats/target/local/controller')
+        self.assertEqual(response.status_code, 200)
+        results = simplejson.loads(response.content)
+        self.assertEqual(len(results.keys()), 1)
+        self.assertTrue('192.168.1.1' in results)
+        controller_info = results['192.168.1.1']
+        #self.assertEqual(controller_info['controller'], local_controller_id)
+        self.assertEqual(controller_info['last-updated'], make_timestamp(10,11))
+
+        # Check getting the info for the switch target type
+        response = test_get_rest_data('v1/stats/target/local/switch')
+        self.assertEqual(response.status_code, 200)
+        results = simplejson.loads(response.content)
+        self.assertEqual(len(results.keys()), 1)
+        self.assertTrue('00:01:02:03:04:05' in results)
+        switch_info = results['00:01:02:03:04:05']
+        self.assertEqual(switch_info['controller'], local_controller_id)
+        self.assertEqual(switch_info['last-updated'], make_timestamp(1,4))
+    
+    def check_stats_type_attributes(self, attributes, expected_last_updated,
+                                    expected_target_type):
+        last_updated = attributes.get('last-updated')
+        self.assertEqual(last_updated, expected_last_updated)
+        target_type = attributes.get('target-type')
+        self.assertEqual(target_type, expected_target_type)
+        
+    def test_stats_type_index(self):
+        response = test_get_rest_data('v1/stats/index/local/controller/192.168.1.1')
+        self.assertEqual(response.status_code, 200)
+        results = simplejson.loads(response.content)
+        self.assertEqual(len(results), 2)
+        attributes = results['cpu-system']
+        self.assertEqual(len(attributes), 1)
+        self.assertEqual(attributes['last-updated'], make_timestamp(10,11))
+        attributes = results['cpu-idle']
+        self.assertEqual(len(attributes), 1)
+        self.assertEqual(attributes['last-updated'], make_timestamp(1,5))
+
+        response = test_get_rest_data('v1/stats/index/local/switch/00:01:02:03:04:05')
+        self.assertEqual(response.status_code, 200)
+        results = simplejson.loads(response.content)
+        self.assertEqual(len(results), 2)
+        attributes = results['flow-count']
+        self.assertEqual(len(attributes), 1)
+        self.assertEqual(attributes['last-updated'], make_timestamp(1,2))
+        attributes = results['packet-count']
+        self.assertEqual(len(attributes), 2)
+        self.assertEqual(attributes['last-updated'], make_timestamp(1,2))
+        parameters = attributes['parameters']
+        self.assertEqual(len(parameters), 2)
+        attributes = parameters['arp']
+        self.assertEqual(len(attributes), 1)
+        self.assertEqual(attributes['last-updated'], make_timestamp(1,3))
+        attributes = parameters['lldp']
+        self.assertEqual(len(attributes), 1)
+        self.assertEqual(attributes['last-updated'], make_timestamp(1,4))
+
+        response = test_get_rest_data('v1/stats/index/local/controller/192.168.1.1/cpu-system')
+        self.assertEqual(response.status_code, 200)
+        attributes = simplejson.loads(response.content)
+        self.assertEqual(len(attributes), 1)
+        self.assertEqual(attributes['last-updated'], make_timestamp(10,11))
+        
+class StatsMetadataTest(StatsTestCase):
+    
+    def check_metadata(self, stats_type, stats_metadata):
+        # The name in the metadata should match the stats_type
+        name = stats_metadata.get('name')
+        self.assertEqual(stats_type, name)
+        
+        # The target_type is a required value, so it should be present in the metadata
+        target_type = stats_metadata.get('target_type')
+        self.assertNotEqual(target_type, None)
+        
+        # NOTE: The following assertion works for now, since we only support these
+        # two target types. Eventually we may support other target types (in which
+        # case we'd need to add the new ones to the tuple) or else custom target
+        # types can be added (in which case we'd maybe want to remove this assertion.
+        self.assertTrue(target_type in ('controller','switch'))
+        
+        # verbose_name is set automatically by the REST code if it isn't set
+        # explicitly in the metadata, so it should always be present.
+        verbose_name = stats_metadata.get('verbose_name')
+        self.assertNotEqual(verbose_name, None)
+        
+    def test_stats_metadata(self):
+        response = test_get_rest_data('v1/stats/metadata/default')
+        self.assertEqual(response.status_code, 200)
+        stats_metadata_dict = simplejson.loads(response.content)
+        self.assertEqual(type(stats_metadata_dict), dict)
+        for stats_type, stats_metadata in stats_metadata_dict.items():
+            # Check that the metadata looks reasonable
+            self.check_metadata(stats_type, stats_metadata)
+            
+            # Fetch the metadata for the individual stats type and check that it matches
+            response2 = test_get_rest_data('v1/stats/metadata/default/' + stats_type)
+            self.assertEqual(response2.status_code, 200)
+            stats_metadata2 = simplejson.loads(response2.content)
+            self.assertEqual(stats_metadata, stats_metadata2)
+    
+    def test_invalid_stats_type(self):
+        # Try getting a stats type that doesn't exist
+        response = test_get_rest_data('v1/stats/metadata/default/foobar')
+        self.assertEqual(response.status_code, 404)
+        error_result = simplejson.loads(response.content)
+        self.assertEqual(error_result.get('error_type'), 'RestResourceNotFoundException')
+        
+class LatestStatTest(StatsTestCase):
+
+    def do_latest_stat(self, target_type, target_id):
+        current_timestamp = int(time.time() * 1000)
+        for i in range(23,-1,-1):
+            # Try with different offsets. Sort of arbitrary list here. Potentially add
+            # new offsets to test specific edge cases
+            offset_list = [0, 3599999, 100, 30000, 400000, 3000000]
+            timestamp = current_timestamp - (i * 3600000) - offset_list[(i+1)%len(offset_list)]
+            stats_data = {target_type + '-stats': {target_id: {'test-stat': [{'timestamp': timestamp, 'value': i}]}}}
+            response = test_put_rest_data(stats_data, 'v1/stats/data/local')
+            self.assertEqual(response.status_code, 200)
+            response = test_get_rest_data('v1/stats/data/local/%s/%s/test-stat' % (target_type, target_id))
+            self.assertEqual(response.status_code, 200)
+            results = simplejson.loads(response.content)
+            self.assertEqual(timestamp, results[0])
+            self.assertEqual(i, results[1])
+    
+    def test_controller_latest_stat(self):
+        self.do_latest_stat('controller', '192.168.1.1')
+    
+    def test_switch_latest_stat(self):
+        self.do_latest_stat('switch', '00:01:02:03:04:05')
+
+class BasicEventsTest(StatsTestCase):
+    
+    EVENTS_DATA = {
+        '192.168.1.1': [
+            {'timestamp': make_timestamp(1,0), 'component': 'sdnplatform', 'log-level': 'Error', 'message': 'Something bad happened'},
+            {'timestamp': make_timestamp(1,1), 'component': 'sdnplatform', 'log-level': 'Info', 'message': 'Something else happened', 'package': 'net.sdnplatformcontroller.core'},
+            {'timestamp': make_timestamp(1,4), 'component': 'sdnplatform', 'log-level': 'Info', 'message': 'Switch connected: 01:02:03:04:45:56', 'package': 'net.sdnplatformcontroller.core', 'dpid': '01:02:03:04:45:56'},
+            {'timestamp': make_timestamp(2,4), 'component': 'django', 'log-level': 'Info', 'message': 'GET: /rest/v1/model/foo'},
+            {'timestamp': make_timestamp(4,10), 'component': 'cassandra', 'log-level': 'Info', 'message': 'Compaction occurred'},
+            {'timestamp': make_timestamp(4,11), 'component': 'cassandra', 'log-level': 'Info', 'message': 'One more compaction occurred'},
+            {'timestamp': make_timestamp(7,10), 'component': 'cassandra', 'log-level': 'Info', 'message': 'Another compaction occurred'},
+        ]
+    }
+
+    TAGGED_EVENTS_DATA = {
+        '192.168.1.1': [
+            {'timestamp': make_timestamp(10,0), 'pk-tag':'1234', 'component': 'sdnplatform', 'log-level': 'Error', 'message': 'Something bad happened'},
+            {'timestamp': make_timestamp(10,1), 'pk-tag':'5678', 'component': 'sdnplatform', 'log-level': 'Info', 'message': 'Something else happened', 'package': 'net.sdnplatformcontroller.core'},
+        ]
+    }
+
+
+    def check_events_results(self, returned_results, expected_results, message=None):
+        self.assertEqual(expected_results, returned_results, message)
+        #self.assertEqual(len(returned_results), len(expected_results), message)
+        #for i in range(len(returned_results)):
+        #    self.assertEqual(returned_results[i], expected_results[i])
+    
+    def test_events(self):
+        response = test_put_rest_data(self.EVENTS_DATA, 'v1/events/data/default')
+        self.assertEqual(response.status_code, 200)
+        
+        # Get all of the data
+        response = test_get_rest_data('v1/events/data/default/192.168.1.1', {'start-time':make_timestamp(1,0),'end-time':make_timestamp(7,10)})
+        self.assertEqual(response.status_code, 200)
+        results = simplejson.loads(response.content)
+        self.check_events_results(results, self.EVENTS_DATA['192.168.1.1'])
+        
+        # Get just one days data
+        response = test_get_rest_data('v1/events/data/default/192.168.1.1', {'start-time':make_timestamp(1,0),'end-time':make_timestamp(1,4)})
+        self.assertEqual(response.status_code, 200)
+        results = simplejson.loads(response.content)
+        self.check_events_results(results, self.EVENTS_DATA['192.168.1.1'][:3])
+
+        # Get two day range
+        response = test_get_rest_data('v1/events/data/default/192.168.1.1', {'start-time':make_timestamp(1,2),'end-time':make_timestamp(4,11)})
+        self.assertEqual(response.status_code, 200)
+        results = simplejson.loads(response.content)
+        self.check_events_results(results, self.EVENTS_DATA['192.168.1.1'][2:6])
+
+    def test_tagged_events(self):
+        response = test_put_rest_data(self.TAGGED_EVENTS_DATA, 'v1/events/data/default')
+        self.assertEqual(response.status_code, 200)
+        
+        response = test_get_rest_data('v1/events/data/default/192.168.1.1', {'start-time':make_timestamp(10,0),'end-time':make_timestamp(10,2),'include-pk-tag':'true'})
+        self.assertEqual(response.status_code, 200)
+        results = simplejson.loads(response.content)
+        self.check_events_results(results, self.TAGGED_EVENTS_DATA['192.168.1.1'])
+    
+    def test_delete_events(self):
+        response = test_put_rest_data(self.EVENTS_DATA, 'v1/events/data/default')
+        self.assertEqual(response.status_code, 200)
+
+        # Delete all but the first 2 and last 2 events
+        response = test_delete_rest_data('v1/events/data/default/192.168.1.1', {
+            'start-time': self.EVENTS_DATA['192.168.1.1'][2]['timestamp'],
+            'end-time':self.EVENTS_DATA['192.168.1.1'][-3]['timestamp']})
+        self.assertEquals(response.status_code, 200)
+
+        response = test_get_rest_data('v1/events/data/default/192.168.1.1', {'start-time':make_timestamp(1,0),'end-time':make_timestamp(7,10)})
+        self.assertEqual(response.status_code, 200)
+        results = simplejson.loads(response.content)
+        self.check_events_results(results, self.EVENTS_DATA['192.168.1.1'][:2] + self.EVENTS_DATA['192.168.1.1'][-2:])
+        
diff --git a/sdncon/stats/utils.py b/sdncon/stats/utils.py
new file mode 100755
index 0000000..d227a58
--- /dev/null
+++ b/sdncon/stats/utils.py
@@ -0,0 +1,85 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from thrift.transport import TTransport
+from thrift.transport import TSocket
+from thrift.protocol import TBinaryProtocol
+from cassandra import Cassandra
+from cassandra.ttypes import *
+
+# FIXME: This class is derived from the django_cassandra backend.
+# Should refactor this code better.
+
+class CassandraConnection(object):
+    def __init__(self, host, port, keyspace, user, password):
+        self.host = host
+        self.port = port
+        self.keyspace = keyspace
+        self.user = user
+        self.password = password
+        self.transport = None
+        self.client = None
+        self.keyspace_set = False
+        self.logged_in = False
+        
+    def set_keyspace(self):
+        if not self.keyspace_set:
+            self.client.set_keyspace(self.keyspace)
+            self.keyspace_set = True
+    
+    def login(self):
+        # TODO: This user/password auth code hasn't been tested
+        if not self.logged_in:
+            if self.user:
+                credentials = {'username': self.user, 'password': self.password}
+                self.client.login(AuthenticationRequest(credentials))
+            self.logged_in = True
+            
+    def connect(self, set_keyspace=False, login=False):
+        if self.transport == None:
+            # Create the client connection to the Cassandra daemon
+            socket = TSocket.TSocket(self.host, int(self.port))
+            transport = TTransport.TFramedTransport(TTransport.TBufferedTransport(socket))
+            protocol = TBinaryProtocol.TBinaryProtocolAccelerated(transport)
+            transport.open()
+            self.transport = transport
+            self.client = Cassandra.Client(protocol)
+            
+        if login:
+            self.login()
+        
+        if set_keyspace:
+            self.set_keyspace()
+                
+    def disconnect(self):
+        if self.transport != None:
+            self.transport.close()
+            self.transport = None
+            self.client = None
+            self.keyspace_set = False
+            self.logged_in = False
+            
+    def is_connected(self):
+        return self.transport != None
+    
+    def reconnect(self):
+        self.disconnect()
+        self.connect(True, True)
+    
+    def get_client(self):
+        if self.client == None:
+            self.connect(True,True)
+        return self.client
diff --git a/sdncon/stats/views.py b/sdncon/stats/views.py
new file mode 100755
index 0000000..5172cc1
--- /dev/null
+++ b/sdncon/stats/views.py
@@ -0,0 +1,364 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from cassandra.ttypes import *
+from django.conf import settings
+from django.http import HttpResponse
+from django.utils import simplejson
+from functools import wraps
+import time
+from .data import StatsException, StatsInvalidStatsDataException, \
+    StatsInvalidStatsTypeException, \
+    get_stats_db_connection, init_stats_db_connection, \
+    get_stats_metadata, get_stats_type_index, \
+    get_stats_target_types, get_stats_targets, delete_stats_data, \
+    get_stats_data, get_latest_stat_data, put_stats_data, \
+    get_closest_sample_interval, get_closest_window_interval, \
+    get_log_event_data, put_log_event_data, delete_log_event_data, \
+    VALUE_DATA_FORMAT
+
+from sdncon.rest.views import RestException, \
+    RestInvalidPutDataException, RestMissingRequiredQueryParamException,\
+    RestInvalidMethodException, RestDatabaseConnectionException,\
+    RestInternalException, RestResourceNotFoundException, \
+    safe_rest_view, JSON_CONTENT_TYPE, get_successful_response
+from sdncon.controller.config import get_local_controller_id
+
+
+class RestStatsException(RestException):
+    def __init__(self, stats_exception):
+        super(RestStatsException,self).__init__('Error accessing stats: ' + str(stats_exception))
+        
+class RestStatsInvalidTimeDurationUnitsException(RestException):
+    def __init__(self, units):
+        super(RestStatsInvalidTimeDurationUnitsException,self).__init__('Invalid time duration units: ' + str(units))
+
+
+class RestStatsInvalidTimeRangeException(RestException):
+    def __init__(self):
+        super(RestStatsInvalidTimeRangeException,self).__init__('Invalid time range specified in stats REST API. '
+            '2 out of 3 of start-time, end-time, and duration params must be specified.')
+
+
+@safe_rest_view
+def safe_stats_rest_view(func, *args, **kwargs):
+    try:
+        request = args[0]
+        response = func(*args, **kwargs)
+    except RestException:
+        raise
+    except StatsInvalidStatsDataException:
+        raise RestInvalidPutDataException()
+    except StatsInvalidStatsTypeException:
+        raise RestResourceNotFoundException(request.path)
+    except StatsException, e:
+        raise RestStatsException(e)
+    except Exception, e:
+        raise RestInternalException(e)
+    return response
+
+
+def safe_stats_view(func):
+    """
+    This is a decorator that takes care of exception handling for the
+    stats views so that stats exceptions are converted to the appropriate
+    REST exception.
+    """
+    @wraps(func)
+    def _func(*args, **kwargs):
+        response = safe_stats_rest_view(func, *args, **kwargs)
+        return response
+    
+    return _func
+
+
+def init_db_connection():
+    db_connection = get_stats_db_connection()
+    if not db_connection:
+        try:
+            stats_db_settings = settings.STATS_DATABASE
+        except Exception:
+            stats_db_settings = {}
+            
+        host = stats_db_settings.get('HOST', 'localhost')
+        port = stats_db_settings.get('PORT', 9160)
+        keyspace = stats_db_settings.get('NAME', 'sdnstats')
+        user = stats_db_settings.get('USER')
+        password = stats_db_settings.get('PASSWORD')
+        replication_factor = stats_db_settings.get('CASSANDRA_REPLICATION_FACTOR', 1)
+        column_family_def_default_settings = stats_db_settings.get('CASSANDRA_COLUMN_FAMILY_DEF_DEFAULT_SETTINGS', {})
+        
+        init_stats_db_connection(host, port, keyspace, user, password, replication_factor, column_family_def_default_settings)
+            
+        db_connection = get_stats_db_connection()
+        assert(db_connection is not None)
+
+START_TIME_QUERY_PARAM = 'start-time'
+END_TIME_QUERY_PARAM = 'end-time'
+DURATION_QUERY_PARAM = 'duration'
+SAMPLE_INTERVAL_QUERY_PARAM = 'sample-interval'
+SAMPLE_COUNT_QUERY_PARAM = 'sample-count'
+SAMPLE_WINDOW_QUERY_PARAM = 'sample-window'
+DATA_FORMAT_QUERY_PARAM = 'data-format'
+LIMIT_QUERY_PARAM = 'limit'
+INCLUDE_PK_TAG_QUERY_PARAM = 'include-pk-tag'
+
+DEFAULT_SAMPLE_COUNT = 50
+
+def convert_time_point(time_point):
+    
+    if time_point is None:
+        return None
+    
+    if time_point:
+        time_point = time_point.lower()
+        if time_point in ('now', 'current'):
+            time_point = int(time.time() * 1000)
+        else:
+            time_point = int(time_point)
+    
+    return time_point
+
+
+UNIT_CONVERSIONS = (
+    (('h', 'hour', 'hours'), 3600000),
+    (('d', 'day', 'days'), 86400000),
+    (('w', 'week', 'weeks'), 604800000),
+    (('m', 'min', 'mins', 'minute', 'minutes'), 60000),
+    (('s', 'sec', 'secs', 'second', 'seconds'), 1000),
+    (('ms', 'millisecond', 'milliseconds'), 1)
+)
+
+def convert_time_duration(duration):
+    
+    if duration is None:
+        return None
+    
+    value = ""
+    for c in duration:
+        if not c.isdigit():
+            break
+        value += c
+    
+    units = duration[len(value):].lower()
+    value = int(value)
+    
+    if units:
+        converted_value = None
+        for conversion in UNIT_CONVERSIONS:
+            if units in conversion[0]:
+                converted_value = value * conversion[1]
+                break
+        if converted_value is None:
+            raise RestStatsInvalidTimeDurationUnitsException(units)
+        
+        value = converted_value
+        
+    return value
+
+
+def get_time_range(start_time, end_time, duration):
+    
+    if not start_time and not end_time and not duration:
+        return (None, None)
+    
+    start_time = convert_time_point(start_time)
+    end_time = convert_time_point(end_time)
+    duration = convert_time_duration(duration)
+    
+    if start_time:
+        if not end_time and duration:
+            end_time = start_time + duration
+    elif end_time and duration:
+        start_time = end_time - duration
+        
+    if not start_time or not end_time:
+        raise RestStatsInvalidTimeRangeException()
+    
+    return (start_time, end_time)
+
+
+def get_time_range_from_request(request):
+    start_time = request.GET.get(START_TIME_QUERY_PARAM)
+    end_time = request.GET.get(END_TIME_QUERY_PARAM)
+    duration = request.GET.get(DURATION_QUERY_PARAM)
+    
+    return get_time_range(start_time, end_time, duration)
+
+#def get_stats_time_range(request):
+#    start_time = request.GET.get(START_TIME_QUERY_PARAM)
+#    end_time = request.GET.get(END_TIME_QUERY_PARAM)
+#    
+#    if not start_time and not end_time:
+#        return None
+#
+#    if not start_time:
+#        raise RestMissingRequiredQueryParamException(START_TIME_QUERY_PARAM)
+#    if not end_time:
+#        raise RestMissingRequiredQueryParamException(END_TIME_QUERY_PARAM)
+#    
+#    return (start_time, end_time)
+
+
+@safe_stats_view
+def do_get_stats(request, cluster, target_type, target_id, stats_type):
+    
+    # FIXME: Hack to handle the old hard-coded controller id value
+    if target_type == 'controller' and target_id == 'localhost':
+        target_id = get_local_controller_id()
+    
+    # Get the time range over which we're getting the stats
+    start_time, end_time = get_time_range_from_request(request)
+    
+    init_db_connection()
+    
+    if request.method == 'GET':
+        window = request.GET.get(SAMPLE_WINDOW_QUERY_PARAM, 0)
+        if window:
+            window = convert_time_duration(window)
+        if window != 0:
+            window = get_closest_window_interval(int(window))
+        # FIXME: Error checking on window value
+                    
+        data_format = request.GET.get(DATA_FORMAT_QUERY_PARAM, VALUE_DATA_FORMAT)
+        # FIXME: Error checking on data_format value
+        
+        limit = request.GET.get(LIMIT_QUERY_PARAM)
+        if limit:
+            limit = int(limit)
+        # FIXME: Error checking on limit value
+    
+        if start_time is not None and end_time is not None:
+            # FIXME: Error checking on start_time and end_time values
+            sample_interval = request.GET.get(SAMPLE_INTERVAL_QUERY_PARAM)
+            if not sample_interval:
+                # FIXME: Error checking on sample_period value
+                sample_count = request.GET.get(SAMPLE_COUNT_QUERY_PARAM, DEFAULT_SAMPLE_COUNT)
+                # FIXME: Error checking on sample_count value
+                    
+                sample_interval = (end_time - start_time) / int(sample_count)
+            else:
+                sample_interval = convert_time_duration(sample_interval)
+            
+            if sample_interval != 0:
+                sample_interval = get_closest_sample_interval(sample_interval)
+            
+            stats_data = get_stats_data(cluster, target_type, target_id,
+                stats_type, start_time, end_time, sample_interval, window, data_format, limit)
+        else:
+            stats_data = get_latest_stat_data(cluster, target_type, target_id, stats_type, window, data_format)
+            
+        response_data = simplejson.dumps(stats_data)
+        response = HttpResponse(response_data, JSON_CONTENT_TYPE)
+        
+    elif request.method == 'DELETE':
+        delete_stats_data(cluster, target_type, target_id, stats_type,
+                      start_time, end_time)
+        response = get_successful_response()
+    else:
+        raise RestInvalidMethodException()
+        
+    return response
+    
+
+@safe_stats_view
+def do_get_stats_metadata(request, cluster, stats_type=None):
+    metadata = get_stats_metadata(cluster, stats_type)
+    response_data = simplejson.dumps(metadata)
+    return HttpResponse(response_data, JSON_CONTENT_TYPE)
+
+
+@safe_stats_view
+def do_get_stats_type_index(request, cluster, target_type, target_id, stats_type=None):
+    # FIXME: Hack to handle the old hard-coded controller id value
+    if target_type == 'controller' and target_id == 'localhost':
+        target_id = get_local_controller_id()
+    init_db_connection()
+    index_data = get_stats_type_index(cluster, target_type, target_id, stats_type)
+    response_data = simplejson.dumps(index_data)
+    return HttpResponse(response_data, JSON_CONTENT_TYPE)
+
+
+@safe_stats_view
+def do_get_stats_target_types(request, cluster):
+    init_db_connection()
+    target_type_data = get_stats_target_types(cluster)
+    response_data = simplejson.dumps(target_type_data)
+    return HttpResponse(response_data, JSON_CONTENT_TYPE)
+
+
+@safe_stats_view
+def do_get_stats_targets(request, cluster, target_type=None):
+    init_db_connection()
+    target_data = get_stats_targets(cluster, target_type)
+    response_data = simplejson.dumps(target_data)
+    return HttpResponse(response_data, JSON_CONTENT_TYPE)
+
+
+@safe_stats_view
+def do_put_stats(request, cluster):
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    
+    init_db_connection()
+    
+    stats_data = simplejson.loads(request.raw_post_data)
+    put_stats_data(cluster, stats_data)
+    
+    response = get_successful_response()
+    
+    return response
+
+
+@safe_stats_view
+def do_get_events(request, cluster, node_id):
+    # FIXME: Hack to handle the old hard-coded controller id value
+    if node_id == 'localhost':
+        node_id = get_local_controller_id()
+    
+    # Get the time range over which we're getting the events
+    start_time, end_time = get_time_range_from_request(request)
+    
+    init_db_connection()
+    
+    if request.method == 'GET':
+        include_pk_tag_param = request.GET.get(INCLUDE_PK_TAG_QUERY_PARAM, 'false')
+        include_pk_tag = include_pk_tag_param.lower() == 'true'
+        events_list = get_log_event_data(cluster, node_id, start_time, end_time, include_pk_tag)
+        response_data = simplejson.dumps(events_list)
+        response = HttpResponse(response_data, JSON_CONTENT_TYPE)
+    elif request.method == 'DELETE':
+        delete_log_event_data(cluster, node_id, start_time, end_time)
+        response = get_successful_response()
+    else:
+        raise RestInvalidMethodException()
+        
+    return response
+
+@safe_stats_view
+def do_put_events(request, cluster):
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    
+    init_db_connection()
+    
+    events_data = simplejson.loads(request.raw_post_data)
+    put_log_event_data(cluster, events_data)
+    
+    response = get_successful_response()
+    
+    return response
+
diff --git a/sdncon/stats_metadata/__init__.py b/sdncon/stats_metadata/__init__.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/sdncon/stats_metadata/__init__.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
diff --git a/sdncon/stats_metadata/of_stats_metadata.py b/sdncon/stats_metadata/of_stats_metadata.py
new file mode 100755
index 0000000..00d6b1d
--- /dev/null
+++ b/sdncon/stats_metadata/of_stats_metadata.py
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+STATS_METADATA = [
+    {'name': 'OFPacketIn', 'type':'int', 'target_type':'switch', 'verbose_name': 'OF Packet In', 'units': 'Packets'},
+    {'name': 'OFFlowMod', 'type':'int', 'target_type':'switch', 'verbose_name': 'OF Flow Mod', 'units': 'Flow Mods'},
+    {'name': 'OFActiveFlow', 'type':'int', 'target_type':'switch', 'verbose_name': 'OF Active Flow', 'units': 'Flows'},
+]
\ No newline at end of file
diff --git a/sdncon/stats_metadata/os_stats_metadata.py b/sdncon/stats_metadata/os_stats_metadata.py
new file mode 100755
index 0000000..8601f83
--- /dev/null
+++ b/sdncon/stats_metadata/os_stats_metadata.py
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+STATS_METADATA = [
+    {'name': 'cpu-idle', 'type':'float', 'target_type':'controller', 'verbose_name': 'CPU Idle', 'units': '%'},
+    {'name': 'cpu-nice', 'type':'float', 'target_type':'controller', 'verbose_name': 'CPU Nice', 'units': '%'},
+    {'name': 'cpu-user', 'type':'float', 'target_type':'controller', 'verbose_name': 'CPU User', 'units': '%'},
+    {'name': 'cpu-system', 'type':'float', 'target_type':'controller', 'verbose_name': 'CPU System', 'units': '%'},
+    {'name': 'mem-used', 'type':'int', 'target_type':'controller', 'verbose_name': 'Memory Used', 'units': 'kB'},
+    {'name': 'mem-free', 'type':'int', 'target_type':'controller', 'verbose_name': 'Memory Free', 'units': 'kB'},
+    {'name': 'swap-used', 'type':'int', 'target_type':'controller', 'verbose_name': 'Swap Used', 'units': 'kB'},
+    {'name': 'disk-root', 'type':'int', 'target_type':'controller', 'verbose_name': '/ Used', 'units': '%'},
+    {'name': 'disk-log', 'type':'int', 'target_type':'controller', 'verbose_name': '/log Used', 'units': '%'},
+    {'name': 'disk-boot', 'type':'int', 'target_type':'controller', 'verbose_name': '/sysboot Used', 'units': '%'},
+    {'name': 'sdnplatform-cpu', 'type':'float', 'target_type':'controller', 'verbose_name': 'SDNPlatform CPU', 'units': '%'},
+    {'name': 'database-cpu', 'type':'float', 'target_type':'controller', 'verbose_name': 'Database CPU', 'units': '%'},
+    {'name': 'apache-cpu', 'type':'float', 'target_type':'controller', 'verbose_name': 'Apache CPU', 'units': '%'},
+    {'name': 'cli-cpu', 'type':'float', 'target_type':'controller', 'verbose_name': 'Cli CPU', 'units': '%'},
+    {'name': 'statd-cpu', 'type':'float', 'target_type':'controller', 'verbose_name': 'Statd CPU', 'units': '%'},
+]
diff --git a/sdncon/syncd/__init__.py b/sdncon/syncd/__init__.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/sdncon/syncd/__init__.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
diff --git a/sdncon/syncd/models.py b/sdncon/syncd/models.py
new file mode 100755
index 0000000..c83461c
--- /dev/null
+++ b/sdncon/syncd/models.py
@@ -0,0 +1,120 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.db import models
+"""
+class SyncdConfig(models.Model):
+    
+    # id is set to the local cluster id.
+    id = models.CharField(
+        primary_key=True,
+        max_length=128)
+    
+    # Enable syncing to the cloud
+    enabled = models.BooleanField(
+        verbose_name='Enabled',
+        help_text='Is syncing to the cloud enabled',
+        default=False)
+    
+    # Log level for the syncd daemon process
+    log_level = models.CharField(
+        max_length=32,
+        verbose_name='Log Level',
+        help_text='Log level for the syncd daemon process',
+        default='warning')
+
+    sync_period = models.PositiveIntegerField(
+        verbose_name='Sync Period',
+        help_text='How often (in seconds) local data is synced to the cloud',
+        default=300)
+    
+    sync_overlap = models.PositiveIntegerField(
+        verbose_name='Sync Overlap',
+        help_text='Overlap (in seconds) of the time range of a sync iteration with the previous sync iteration',
+        default=30)
+    
+    class Rest:
+        NAME = 'syncd-config'
+        FIELD_INFO = (
+            {'name': 'log_level', 'rest_name': 'log-level'},
+            {'name': 'sync_period', 'rest_name': 'sync-period'},
+            {'name': 'sync_overlap', 'rest_name': 'sync-overlap'},
+        )
+
+class SyncdTransportConfig(models.Model):
+    
+    # Composite key of <syncd-config-id>:<transport-name>
+    id = models.CharField(
+        primary_key=True,
+        max_length=256)
+    
+    config = models.ForeignKey(
+        SyncdConfig,
+        blank=True,
+        null=True)
+
+    name = models.CharField(
+        max_length=128,
+        blank=True,
+        null=True)
+    
+    type = models.CharField(
+        max_length=32,
+        blank=True,
+        null=True)
+    
+    args = models.TextField(
+        blank=True,
+        null=True)
+
+    target_cluster = models.CharField(
+        max_length=256,
+        blank=True,
+        null=True)
+    
+    class Rest:
+        NAME = 'syncd-transport-config'
+        FIELD_INFO = (
+            {'name': 'target_cluster', 'rest_name': 'target-cluster'},
+        )
+
+class SyncdProgressInfo(models.Model):
+    
+    # id value is per-controller-node and per-syncd-transport, so the id is
+    # <controller-node id>:<transport-name>
+    id = models.CharField(
+        primary_key=True,
+        max_length=256)
+
+    data_start_time = models.PositiveIntegerField(
+        verbose_name='Data Start Time',
+        help_text='Timestamp of earliest data available for syncing',
+        blank=True,
+        null=True)
+    
+    last_sync_time = models.PositiveIntegerField(
+        verbose_name='Last Sync Time',
+        help_text='Last time that data was successfully synced to the cloud from the local controller node',
+        blank=True,
+        null=True)
+
+    class Rest:
+        NAME = 'syncd-progress-info'
+        FIELD_INFO = (
+            {'name': 'data_start_time', 'rest_name': 'data-start-time'},
+            {'name': 'last_sync_time', 'rest_name': 'last-sync-time'},
+        )
+"""
\ No newline at end of file
diff --git a/sdncon/syncd/tests.py b/sdncon/syncd/tests.py
new file mode 100755
index 0000000..b6c00b2
--- /dev/null
+++ b/sdncon/syncd/tests.py
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+# Add unit tests here
diff --git a/sdncon/syncd/views.py b/sdncon/syncd/views.py
new file mode 100755
index 0000000..84e1e7a
--- /dev/null
+++ b/sdncon/syncd/views.py
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+# Create your views here.
+
diff --git a/sdncon/ui/__init__.py b/sdncon/ui/__init__.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/sdncon/ui/__init__.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
diff --git a/sdncon/ui/scripts/__init__.py b/sdncon/ui/scripts/__init__.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/sdncon/ui/scripts/__init__.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
diff --git a/sdncon/ui/scripts/buildtopology.py b/sdncon/ui/scripts/buildtopology.py
new file mode 100755
index 0000000..2d7e940
--- /dev/null
+++ b/sdncon/ui/scripts/buildtopology.py
@@ -0,0 +1,124 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+#
+# Build a simple JSON of the topology for use in the ForceDirected 
+# Visualization in the InfoVis Toolkit
+#
+
+#Importing modules
+import re
+import sys
+import time
+import json
+import urllib2
+import switchalias
+from sdncon.rest.views import do_switches, do_model_list, do_instance, do_device, do_links
+
+def build_topology_data(request):
+    
+    # Query JSON from API and load into dictionary
+    switches = json.loads(do_switches(request).content)
+    devices = json.loads(do_device(request).content)
+    links = json.loads(do_links(request).content)
+    aliasDict = switchalias.aliasDict(request)
+    
+    # Dictionaries
+    parsedswitch = []
+    parseddevices = []
+    parsedlinks = []
+    
+    # Step through master 'switches' list, extract entry for each dictionary.
+    for index_switches,value1_switches in enumerate(switches):
+      tempdict = {}
+    
+      # get needed entries in 'switches'
+      tempdict['dpid'] = value1_switches.get('dpid','')
+      tempdict['inetAddress'] = value1_switches.get('inetAddress','')
+      
+      # append to final sorted output.
+      parsedswitch.append(tempdict)
+     
+    # Step through master 'device' list, extract entry for each dictionary.
+    for index_devices,value1_devices in enumerate(devices):
+      tempdict = {}
+    
+      # get needed entries in 'devices'
+      for index_mac,value_mac in enumerate(value1_devices['mac']):
+        tempdict['mac'] = value_mac
+      tempdict['ipv4'] = value1_devices.get('ipv4','Unknown')
+      for index_switch2,value_switch2 in enumerate(value1_devices['attachmentPoint']):
+        switchconnlist = []
+        switchtempdict = {}
+        if value_switch2.get('switchDPID', 'UNKNOWN') != '':
+          if value_switch2.get('port', 'UNKNOWN') != '':
+            switchtempdict['port'] = value_switch2['port']
+            switchtempdict['DPID'] = value_switch2['switchDPID']
+            switchconnlist.append(switchtempdict)
+            tempdict['attachments'] = switchconnlist
+      # append to final sorted output.
+      parseddevices.append(tempdict)
+    
+    
+    # Step through master 'links' list, extract entry for each dictionary.
+    for index_links,value1_links in enumerate(links):
+      tempdict = {}
+    
+      # get needed entries in 'links'
+      tempdict['src-switch'] = value1_links.get('src-switch','')
+      tempdict['src-port'] = value1_links.get('src-port','')
+      tempdict['src-port-state'] = value1_links.get('src-port-state','')
+      tempdict['dst-switch'] = value1_links.get('dst-switch','')
+      tempdict['dst-port'] = value1_links.get('dst-port','')
+      tempdict['dst-port-state'] = value1_links.get('dst-port-state','')
+    
+      # append to final sorted output.
+      parsedlinks.append(tempdict)
+    
+    #Begin puting the data in the JSON list
+    jsonoutput = []
+    result = ''
+    
+    
+    # Print switches by themselves to handle orphaned switches.
+    for index_switch,value_switch in enumerate(parsedswitch):
+      adjacenciestmp = []
+      datatmp = {}
+      
+      datatmp = { '$color': '#f15922', '$type': 'square', '$dim': '10'}
+      jsonoutput.append({'adjacencies': [], 'data': datatmp, 'id': value_switch['dpid'], 'name': aliasDict.get(value_switch['dpid'], value_switch['dpid'])})
+    
+    
+    # Determine host -> Switch links
+    for index_devices,value_devices in enumerate(parseddevices):
+      adjacenciestmp = []
+      datatmp = {}
+      
+      for index_adj,value_adj in enumerate(value_devices.get('attachments', '')):
+        adjacenciestmp.append({'nodeTo': str(value_adj['DPID']), 'nodeFrom': value_devices['mac'], 'data': { '$color': '#fdb813', '$lineWidth': '3' }})
+      datatmp = { '$color': '#fdb813', '$type': 'circle', '$dim': '10'}
+      jsonoutput.append({'adjacencies': adjacenciestmp, 'data': datatmp, 'id': value_devices['mac'], 'name': value_devices['mac']})
+    
+    # Determine Switch -> Switch links
+    for index_link,value_link in enumerate(parsedlinks):
+      adjacenciestmp = []
+      datatmp = {}
+      adjacenciestmp.append({'nodeTo': str(value_link['src-switch']), 'nodeFrom': value_link['dst-switch'], 'data': { '$color': '#f15922', '$lineWidth': '3' }})
+      datatmp = { '$color': '#f15922', '$type': 'square', '$dim': '10'}
+      jsonoutput.append({'adjacencies': adjacenciestmp, 'data': datatmp, 'id': value_link['dst-switch'], 'name': aliasDict.get(value_link['dst-switch'], value_link['dst-switch'])})
+    
+    result += 'var json =' + json.dumps(jsonoutput, sort_keys=True, indent=4, separators=(',', ': ')) + ';'
+    return result 
\ No newline at end of file
diff --git a/sdncon/ui/scripts/showhost.py b/sdncon/ui/scripts/showhost.py
new file mode 100755
index 0000000..9c72fb5
--- /dev/null
+++ b/sdncon/ui/scripts/showhost.py
@@ -0,0 +1,106 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+#
+# Python script for querying API and displaying connected hosts in a table
+#
+#
+
+#Importing modules
+import re
+import sys
+import time
+import datetime
+import json
+import urllib2
+import switchalias
+from sdncon.rest.views import do_switches, do_model_list, do_instance, do_device
+
+def show_host_data(request):
+
+    # Query JSON from API and load into dictionary
+    switches = json.loads(do_switches(request).content)
+    switchdevices = json.loads(do_device(request).content)
+    
+    # Dictionaries
+    sorteddict = []
+    aliasDict = switchalias.aliasDict(request)
+    unsortdict = []
+     
+    # Step through master 'device' list, extract entry for each dictionary.
+    for index_devices,value1_devices in enumerate(switchdevices):
+      tempdict = {}
+      tempswitchdict = {}
+    
+      # get needed entries in 'devices'
+      tempdict['mac'] = value1_devices.get('mac','')
+      tempdict['entityClass'] = value1_devices.get('entityClass','')
+      tempdict['vlan'] = value1_devices.get('vlan','')
+      tempdict['ipv4'] = value1_devices.get('ipv4','Unknown')
+      tempdict['switch'] = value1_devices.get('attachmentPoint','')
+      tempdict['lastSeen'] = value1_devices.get('lastSeen','')
+    
+      # append to final sorted output.
+      unsortdict.append(tempdict)
+    
+    
+    sorteddict = sorted(unsortdict, key=lambda elem: "%s" % (elem['mac']))
+    
+    #print sorteddict
+    #print time.strftime('%Y-%m-%d %H:%M:%S %Z', time.gmtime(sorteddict[0]['connectedSince'] / float(1000)))
+    
+    result = ''
+    # Print table output
+    result += '<table id="showdeviceoutput" >'
+    result += '<tbody style="border-top: 0px;">'
+    result += '<tr><td>ID</td><td>MAC Address</td><td>Address Space</td><td>VLAN</td><td>IP</td><td>Switch</td><td>Last Seen</td></tr>'
+    for index_output,value_output in enumerate(sorteddict):
+        result += '<tr>'
+        result += '  <td>' + str(index_output + 1) + '</td>'
+        result += '  <td>'
+        for tmp_index,tmp_value in enumerate(value_output['mac']):
+            if tmp_index > 0:
+              result += ', ',
+            result += str(tmp_value)
+        result += '</td>'
+        result += '  <td>' + value_output.get('entityClass','') + '</td>'
+        result += '  <td>'
+        for tmp_index,tmp_value in enumerate(value_output['vlan']):
+            if tmp_index > 0:
+              result += ', ',
+            result += str(tmp_value)
+        result += '</td>'
+        result += '  <td>'
+        for tmp_index,tmp_value in enumerate(value_output['ipv4']):
+            if tmp_index > 0:
+              result += ', ',
+            result += str(tmp_value)
+        result += '</td>'
+        result += '  <td>'
+        for tmp_index,tmp_value in enumerate(value_output['switch']):
+            if tmp_index > 0:
+              result += ', ',
+            result += aliasDict.get(tmp_value.get('switchDPID', 'UNKNOWN'), tmp_value.get('switchDPID', 'UNKNOWN')) + ' Port ' + str(tmp_value.get('port', 'UNKNOWN'))
+        result += '</td>'
+        delta = round(time.time(),0) - (round(value_output.get('lastSeen',time.time()) / int(1000)))
+        if delta <= 0:
+          result += '  <td> Now </td>'
+        else:
+          result += '  <td>' + str(datetime.timedelta(seconds=delta))  + '</td>'
+        result += '</tr>'
+    result += '</tbody>'
+    result += '</table>'  
+    return result
diff --git a/sdncon/ui/scripts/showlink.py b/sdncon/ui/scripts/showlink.py
new file mode 100755
index 0000000..4a91d50
--- /dev/null
+++ b/sdncon/ui/scripts/showlink.py
@@ -0,0 +1,87 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+#
+# Python script to query link states from REST API
+#
+#
+
+#Importing modules
+import re
+import sys
+import time
+import json
+import urllib2
+import switchalias
+from sdncon.rest.views import do_switches, do_model_list, do_instance, do_device, do_links
+
+
+def show_link_data(request):
+
+    # Query JSON from API and load into dictionary
+    switches = json.loads(do_switches(request).content)
+    switchlinks = json.loads(do_links(request).content)
+    
+    # Dictionaries
+    sorteddict = []
+    aliasDict = switchalias.aliasDict(request)
+    unsortdict = []
+    statedict = {0: 'FORWARDING', 1: 'DOWN', 2: 'FORWARD', 3: 'BLOCK', 4: 'MASK'}
+     
+    # Step through master 'links' list, extract entry for each dictionary.
+    for index_links,value1_links in enumerate(switchlinks):
+        tempdict = {}
+        tempswitchdict = {}
+      
+        # get needed entries in 'links'
+        tempdict['src-switch'] = value1_links.get('src-switch','')
+        tempdict['src-port'] = value1_links.get('src-port','')
+        tempdict['src-port-state'] = value1_links.get('src-port-state','')
+        tempdict['dst-switch'] = value1_links.get('dst-switch','')
+        tempdict['dst-port'] = value1_links.get('dst-port','')
+        tempdict['dst-port-state'] = value1_links.get('dst-port-state','')
+        tempdict['type'] = value1_links.get('type','')
+      
+        # append to final sorted output.
+        unsortdict.append(tempdict)
+    
+    
+    sorteddict = sorted(unsortdict, key=lambda elem: "%s %02d" % (elem['src-switch'], elem['src-port']))
+    
+    result = ''
+    # Print table output
+    result += '<table id="showlinkoutput" >'
+    result += '<tbody>'
+    result += '<tr><td>ID</td><td>Source Switch</td><td>Source Port</td><td>Source Port State</td><td>Destination Switch</td><td>Destination Port</td><td>Destination Port State</td><td>Connection Type</td></tr>'
+    for index_output,value_output in enumerate(sorteddict):
+        result += '<tr>'
+        result += '  <td>' + str(index_output + 1) + '</td>'
+        result += '  <td>' 
+        result += aliasDict.get(value_output.get('src-switch', 'UNKNOWN'), value_output.get('src-switch', 'UNKNOWN'))
+        result += '</td>'
+        result += '  <td>' + str(value_output.get('src-port','')) + '</td>'
+        result += '  <td>' + statedict.get(value_output.get('src-port-state',0),'DOWN') + '</td>'
+        result += '  <td>' 
+        result += aliasDict.get(value_output.get('dst-switch', 'UNKNOWN'), value_output.get('dst-switch', 'UNKNOWN'))
+        result += '</td>'
+        result += '  <td>' + str(value_output.get('dst-port','')) + '</td>'
+        result += '  <td>' + statedict.get(value_output.get('dst-port-state',0),'DOWN') + '</td>'
+        result += '  <td>' + value_output.get('type','') + '</td>'
+        result += '</tr>'
+    result += '</tbody>'
+    result += '</table>'
+    return result
+  
diff --git a/sdncon/ui/scripts/showswitch.py b/sdncon/ui/scripts/showswitch.py
new file mode 100755
index 0000000..8b8317e
--- /dev/null
+++ b/sdncon/ui/scripts/showswitch.py
@@ -0,0 +1,88 @@
+#!/usr/bin/python
+#
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# Python script for querying REST API and displaying connected switches in
+# a table 
+#
+
+#Importing modules
+import re
+import sys
+import time
+import json
+import urllib2
+from sdncon.rest.views import do_switches, do_model_list, do_instance
+
+def show_switch_data(request):
+    
+    switches = json.loads(do_switches(request).content)
+    switchaliases = json.loads(do_instance(request, 'switch-alias').content)
+    switchconfig = json.loads(do_instance(request, "switch-config").content)
+
+    # Dictionaries
+    sorteddict = []
+     
+    # Step through master 'switches' list, extract entry for each dictionary.
+    for index_switches,value1_switches in enumerate(switches):
+      tempdict = {}
+      tempaliasdict = {}
+      tempconfigdict = {}
+    
+      # get needed entries in 'switches'
+      tempdict['dpid'] = value1_switches.get('dpid','')
+      tempdict['inetAddress'] = value1_switches.get('inetAddress','')
+      tempdict['connectedSince'] = value1_switches.get('connectedSince','')
+    
+      # get related entries in other JSON queries
+      for index_switchaliases,value1_switchaliases in enumerate(switchaliases):
+        if value1_switchaliases['switch'] == value1_switches['dpid']:
+          tempaliasdict['alias'] = value1_switchaliases.get('id','')
+      tempdict['alias'] = tempaliasdict.get('alias','')
+    
+      for index_switchconfig,value1_switchconfig in enumerate(switchconfig):
+        if value1_switchconfig['dpid'] == value1_switches['dpid']:
+          tempconfigdict['core-switch'] = value1_switchconfig.get('core-switch','')
+          tempconfigdict['tunnel-termination'] = value1_switchconfig.get('tunnel-termination','')
+      tempdict['core-switch'] = tempconfigdict.get('core-switch','')
+      tempdict['tunnel-termination'] = tempconfigdict.get('tunnel-termination','')
+      
+      # append to final sorted output.
+      sorteddict.append(tempdict)
+    sorteddict.reverse()
+    
+    result = ''
+    # Print table output
+    result += '<table id="showswitchoutput">'
+    result += '<tbody>'
+    result += '<tr><td>ID</td><td>Alias</td><td>Switch DPID</td><td>IP Address</td><td>Connected Since</td></tr>'
+    for index_output,value_output in enumerate(sorteddict):
+      formatIPresult = re.search('/(.*):',value_output['inetAddress'])
+      result += '<tr>'
+      result += '  <td>' + str(index_output + 1) + '</td>'
+      result += '  <td>' + value_output.get('alias','') + '</td>'
+      result += '  <td>' + value_output.get('dpid','') + '</td>'
+      result += '  <td>' + formatIPresult.group(1) + '</td>'
+      if value_output['connectedSince'] != '':
+        result += '  <td>' + time.strftime('%Y-%m-%d %H:%M:%S %Z', time.gmtime(value_output['connectedSince'] / float(1000))) + '</td>'
+      else:
+        result += '  <td>Disconnected</td>'
+      result += '</tr>'
+    result += '</tbody>'
+    result += '</table>'
+    
+    return result
+
diff --git a/sdncon/ui/scripts/showtunnel.py b/sdncon/ui/scripts/showtunnel.py
new file mode 100755
index 0000000..a8c0545
--- /dev/null
+++ b/sdncon/ui/scripts/showtunnel.py
@@ -0,0 +1,82 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+#
+# Python script to query tunnel states from REST API
+#
+#
+
+#Importing modules
+import re
+import sys
+import time
+import json
+import urllib2
+import switchalias
+from sdncon.rest.views import do_sdnplatform_tunnel_manager
+
+def show_tunnel_data(request):
+
+    # Query JSON from API and load into dictionary
+    tunnels = json.loads(do_sdnplatform_tunnel_manager(request,'all').content)
+    
+    # Dictionaries
+    sorteddict = []
+    aliasDict = switchalias.aliasDict(request)
+    unsortdict = []
+    statedict = {0: 'FORWARDING', 1: 'DOWN', 2: 'FORWARD', 3: 'BLOCK', 4: 'MASK'}
+     
+    # Step through master 'tunnels' list, extract entry for each dictionary.
+    for index_tunnels,value1_tunnels in tunnels.iteritems():
+      tempdict = {}
+      temptunneldict = {}
+    
+      # get needed entries in 'links' 
+      tempdict['dpid'] = value1_tunnels.get('hexDpid','')
+      tempdict['tunnelEnabled'] = value1_tunnels.get('tunnelEnabled','')
+      tempdict['tunnelIPAddr'] = value1_tunnels.get('tunnelIPAddr','')
+      tempdict['tunnelActive'] = value1_tunnels.get('tunnelActive','')
+      tempdict['tunnelState'] = value1_tunnels.get('tunnelState','')
+      tempdict['tunnelIf'] = value1_tunnels.get('tunnelEndPointIntfName','')
+      tempdict['tunnelCapable'] = value1_tunnels.get('tunnelCapable','')
+      # append to final sorted output.
+      if value1_tunnels.get('tunnelCapable',''):
+        unsortdict.append(tempdict)
+    
+    sorteddict = sorted(unsortdict, key=lambda elem: "%s %s" % (elem['dpid'], elem['tunnelIPAddr']))
+    
+    result = ''
+    # Print table output
+    result += '<table id="showtunneloutput" >'
+    result += '<tbody>'
+    result += '<tr><td>ID</td><td>Switch</td><td>Tunnel Source IP</td><td>Tunnel Interface</td><td>Tunnel Enabled</td><td>Tunnel State</td></tr>'
+    
+    for index_output,value_output in enumerate(sorteddict):
+      result += '<tr>'
+      result += '  <td>' + str(index_output + 1) + '</td>'
+      result += '  <td>' 
+      result += aliasDict.get(value_output.get('dpid', 'UNKNOWN'), value_output.get('dpid', 'UNKNOWN'))
+      result += '</td>'
+      result += '  <td>' + str(value_output.get('tunnelIPAddr','')) + '</td>'
+      result += '  <td>' + value_output.get('tunnelIf','UNKNOWN') + '</td>'
+      result += '  <td>' + str(value_output.get('tunnelActive','')) + '</td>'
+      result += '  <td>' + value_output.get('tunnelState','') + '</td>'
+      result += '</tr>'
+    result += '</tbody>'
+    result += '</table>'
+    return result
+    
+      
\ No newline at end of file
diff --git a/sdncon/ui/scripts/switchalias.py b/sdncon/ui/scripts/switchalias.py
new file mode 100755
index 0000000..768cf60
--- /dev/null
+++ b/sdncon/ui/scripts/switchalias.py
@@ -0,0 +1,42 @@
+#!/usr/bin/python
+#
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# Query REST API, return dictionary with alias to DPID mappings. 
+#
+
+#Importing modules
+import re
+import sys
+import json
+import urllib2
+from sdncon.rest.views import do_instance
+
+def aliasDict(request):
+  
+  # Query JSON from API and load into dictionary
+  rawdict = json.loads(do_instance(request, 'switch-alias').content)
+
+  # Dictionaries
+  aliasdict = {}
+ 
+  # Step through master 'alias' list, extract entry for each dictionary.
+  for index_query,value1_query in enumerate(rawdict):
+
+    # get needed entries in 'alias'
+    aliasdict[value1_query.get('switch','ERR')] = value1_query.get('id',' ')
+
+  return aliasdict
diff --git a/sdncon/ui/static/css/table.css b/sdncon/ui/static/css/table.css
new file mode 100755
index 0000000..4cd9f4d
--- /dev/null
+++ b/sdncon/ui/static/css/table.css
@@ -0,0 +1,213 @@
+/*
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+dynamic table CSS, edited for 2 tables */
+
+.dynamictable {
+	margin:0px;padding:0px;
+        border-top: 0px;
+	/*border:1px solid #e5e5e5;*/
+	width:100%;
+        float: left;
+        position:relative;
+	
+	-moz-border-radius-bottomleft:5px;
+	-webkit-border-bottom-left-radius:5px;
+	border-bottom-left-radius:5px;
+	
+	-moz-border-radius-bottomright:5px;
+	-webkit-border-bottom-right-radius:5px;
+	border-bottom-right-radius:5px;
+	
+	/*-moz-border-radius-topright:5px;
+	-webkit-border-top-right-radius:5px;
+	border-top-right-radius:5px;
+	
+	-moz-border-radius-topleft:5px;
+	-webkit-border-top-left-radius:5px;
+	border-top-left-radius:5px;*/
+}.dynamictable table{
+	width:100%;
+	margin:0px;padding:0px;
+	border-collapse: collapse;
+	border-spacing: 0px;
+}.dynamictable tr:last-child td:last-child {
+	-moz-border-radius-bottomright:5px;
+	-webkit-border-bottom-right-radius:5px;
+	border-bottom-right-radius:5px;
+}
+.dynamictable table tr:first-child td:first-child {
+/*	-moz-border-radius-topleft:5px;
+	-webkit-border-top-left-radius:5px;
+	border-top-left-radius:5px;*/
+}
+.dynamictable table tr:first-child td:last-child {
+/*	-moz-border-radius-topright:5px;
+	-webkit-border-top-right-radius:5px;
+	border-top-right-radius:5px;*/
+}.dynamictable tr:last-child td:first-child{
+	-moz-border-radius-bottomleft:5px;
+	-webkit-border-bottom-left-radius:5px;
+	border-bottom-left-radius:5px;
+}.dynamictable tr:hover td{
+	
+}
+.dynamictable tr:nth-child(odd){ background-color:#e5e5e5; }
+.dynamictable tr:nth-child(even)    { background-color:#ffffff; }.dynamictable td{
+	vertical-align:middle;
+	
+	
+	border-width:0px 1px 1px 0px;
+	text-align:center;
+	padding:7px;
+	font-size:12px;
+	font-family:Helvetica;
+	font-weight:normal;
+	color:#4d4d4f;
+}.dynamictable tr:last-child td{
+	border-width:0px 1px 0px 0px;
+}.dynamictable tr td:last-child{
+	border-width:0px 0px 1px 0px;
+}.dynamictable tr:last-child td:last-child{
+	border-width:0px 0px 0px 0px;
+}
+.dynamictable tr:first-child td{
+		background:-o-linear-gradient(bottom, #fdb813 5%, #fdb813 100%);	background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #fdb813), color-stop(1, #fdb813) );
+	background:-moz-linear-gradient( center top, #fdb813 5%, #fdb813 100% );
+	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#fdb813", endColorstr="#fdb813");	background: -o-linear-gradient(top,#fdb813,fdb813);
+
+	background-color:#fdb813;
+	/*border:0px solid #e5e5e5;*/
+	text-align:center;
+	border-width:0px 0px 1px 1px;
+	font-size:14px;
+	font-family:Helvetica;
+	font-weight:bold;
+	color:#ffffff;
+}
+.dynamictable tr:first-child:hover td{
+	background:-o-linear-gradient(bottom, #fdb813 5%, #fdb813 100%);	background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #fdb813), color-stop(1, #fdb813) );
+	background:-moz-linear-gradient( center top, #fdb813 5%, #fdb813 100% );
+	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#fdb813", endColorstr="#fdb813");	background: -o-linear-gradient(top,#fdb813,fdb813);
+
+	background-color:#fdb813;
+}
+.dynamictable tr:first-child td:first-child{
+	border-width:0px 0px 1px 0px;
+}
+.dynamictable tr:first-child td:last-child{
+	border-width:0px 0px 1px 1px;
+}
+
+/* begin dynamictable 2 */
+
+.dynamictable2 {
+	margin:0px;padding:0px;
+        border-top: 0px;
+	/*border:1px solid #e5e5e5;*/
+	width:100%;
+        float: left;
+        position:relative;
+	
+	-moz-border-radius-bottomleft:5px;
+	-webkit-border-bottom-left-radius:5px;
+	border-bottom-left-radius:5px;
+	
+	-moz-border-radius-bottomright:5px;
+	-webkit-border-bottom-right-radius:5px;
+	border-bottom-right-radius:5px;
+	
+	-moz-border-radius-topright:5px;
+	-webkit-border-top-right-radius:5px;
+	border-top-right-radius:5px;
+	
+	-moz-border-radius-topleft:5px;
+	-webkit-border-top-left-radius:5px;
+	border-top-left-radius:5px;
+}.dynamictable2 table{
+	width:100%;
+	margin:0px;padding:0px;
+	border-collapse: collapse;
+	border-spacing: 0px;
+}.dynamictable2 tr:last-child td:last-child {
+	-moz-border-radius-bottomright:5px;
+	-webkit-border-bottom-right-radius:5px;
+	border-bottom-right-radius:5px;
+}
+.dynamictable2 table tr:first-child td:first-child {
+	-moz-border-radius-topleft:5px;
+	-webkit-border-top-left-radius:5px;
+	border-top-left-radius:5px;
+}
+.dynamictable2 table tr:first-child td:last-child {
+	-moz-border-radius-topright:5px;
+	-webkit-border-top-right-radius:5px;
+	border-top-right-radius:5px;
+}.dynamictable2 tr:last-child td:first-child{
+	-moz-border-radius-bottomleft:5px;
+	-webkit-border-bottom-left-radius:5px;
+	border-bottom-left-radius:5px;
+}.dynamictable2 tr:hover td{
+	
+}
+.dynamictable2 tr:nth-child(odd){ background-color:#f5f5f5; }
+.dynamictable2 tr:nth-child(even)    { background-color:#ffffff; }.dynamictable2 td{
+	vertical-align:middle;
+	
+	
+	border-width:0px 1px 1px 0px;
+	text-align:center;
+	padding:7px;
+	font-size:12px;
+	font-family:Helvetica;
+	font-weight:normal;
+	color:#4d4d4f;
+}.dynamictable2 tr:last-child td{
+	border-width:0px 1px 0px 0px;
+}.dynamictable2 tr td:last-child{
+	border-width:0px 0px 1px 0px;
+}.dynamictable2 tr:last-child td:last-child{
+	border-width:0px 0px 0px 0px;
+}
+.dynamictable2 tr:first-child td{
+		background:-o-linear-gradient(bottom, #fdb813 5%, #fdb813 100%);	background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #fdb813), color-stop(1, #fdb813) );
+	background:-moz-linear-gradient( center top, #fdb813 5%, #fdb813 100% );
+	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#fdb813", endColorstr="#fdb813");	background: -o-linear-gradient(top,#fdb813,fdb813);
+
+	background-color:#fdb813;
+	/*border:0px solid #e5e5e5;*/
+	text-align:center;
+	border-width:0px 0px 1px 1px;
+	font-size:14px;
+	font-family:Helvetica;
+	font-weight:bold;
+	color:#ffffff;
+}
+.dynamictable2 tr:first-child:hover td{
+	background:-o-linear-gradient(bottom, #fdb813 5%, #fdb813 100%);	background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #fdb813), color-stop(1, #fdb813) );
+	background:-moz-linear-gradient( center top, #fdb813 5%, #fdb813 100% );
+	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#fdb813", endColorstr="#fdb813");	background: -o-linear-gradient(top,#fdb813,fdb813);
+
+	background-color:#fdb813;
+}
+.dynamictable2 tr:first-child td:first-child{
+	border-width:0px 0px 1px 0px;
+}
+.dynamictable2 tr:first-child td:last-child{
+	border-width:0px 0px 1px 1px;
+}
+
diff --git a/sdncon/ui/static/css/thirdparty/images/animated-overlay.gif b/sdncon/ui/static/css/thirdparty/images/animated-overlay.gif
new file mode 100755
index 0000000..d441f75
--- /dev/null
+++ b/sdncon/ui/static/css/thirdparty/images/animated-overlay.gif
Binary files differ
diff --git a/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_100_FFFFFF_40x100.png b/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_100_FFFFFF_40x100.png
new file mode 100755
index 0000000..a986cc9
--- /dev/null
+++ b/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_100_FFFFFF_40x100.png
Binary files differ
diff --git a/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_45_e5e5e5_40x100.png b/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_45_e5e5e5_40x100.png
new file mode 100755
index 0000000..4164ac5
--- /dev/null
+++ b/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_45_e5e5e5_40x100.png
Binary files differ
diff --git a/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_50_00a0df_40x100.png b/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_50_00a0df_40x100.png
new file mode 100755
index 0000000..c3b2c5e
--- /dev/null
+++ b/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_50_00a0df_40x100.png
Binary files differ
diff --git a/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_50_fdb813_40x100.png b/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_50_fdb813_40x100.png
new file mode 100755
index 0000000..a9358e4
--- /dev/null
+++ b/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_50_fdb813_40x100.png
Binary files differ
diff --git a/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_55_999999_40x100.png b/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_55_999999_40x100.png
new file mode 100755
index 0000000..8149aa2
--- /dev/null
+++ b/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_55_999999_40x100.png
Binary files differ
diff --git a/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_75_aaaaaa_40x100.png b/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_75_aaaaaa_40x100.png
new file mode 100755
index 0000000..f63adca
--- /dev/null
+++ b/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_75_aaaaaa_40x100.png
Binary files differ
diff --git a/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_75_e5e5e5_40x100.png b/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_75_e5e5e5_40x100.png
new file mode 100755
index 0000000..ae411be
--- /dev/null
+++ b/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_75_e5e5e5_40x100.png
Binary files differ
diff --git a/sdncon/ui/static/css/thirdparty/images/ui-bg_glass_55_f8da4e_1x400.png b/sdncon/ui/static/css/thirdparty/images/ui-bg_glass_55_f8da4e_1x400.png
new file mode 100755
index 0000000..0bf80ae
--- /dev/null
+++ b/sdncon/ui/static/css/thirdparty/images/ui-bg_glass_55_f8da4e_1x400.png
Binary files differ
diff --git a/sdncon/ui/static/css/thirdparty/images/ui-bg_gloss-wave_45_e14f1c_500x100.png b/sdncon/ui/static/css/thirdparty/images/ui-bg_gloss-wave_45_e14f1c_500x100.png
new file mode 100755
index 0000000..dc9f8af
--- /dev/null
+++ b/sdncon/ui/static/css/thirdparty/images/ui-bg_gloss-wave_45_e14f1c_500x100.png
Binary files differ
diff --git a/sdncon/ui/static/css/thirdparty/images/ui-icons_4d4d4f_256x240.png b/sdncon/ui/static/css/thirdparty/images/ui-icons_4d4d4f_256x240.png
new file mode 100755
index 0000000..8662d52
--- /dev/null
+++ b/sdncon/ui/static/css/thirdparty/images/ui-icons_4d4d4f_256x240.png
Binary files differ
diff --git a/sdncon/ui/static/css/thirdparty/images/ui-icons_f47d20_256x240.png b/sdncon/ui/static/css/thirdparty/images/ui-icons_f47d20_256x240.png
new file mode 100755
index 0000000..e48647c
--- /dev/null
+++ b/sdncon/ui/static/css/thirdparty/images/ui-icons_f47d20_256x240.png
Binary files differ
diff --git a/sdncon/ui/static/css/thirdparty/images/ui-icons_f7a50d_256x240.png b/sdncon/ui/static/css/thirdparty/images/ui-icons_f7a50d_256x240.png
new file mode 100755
index 0000000..e084802
--- /dev/null
+++ b/sdncon/ui/static/css/thirdparty/images/ui-icons_f7a50d_256x240.png
Binary files differ
diff --git a/sdncon/ui/static/css/thirdparty/images/ui-icons_fcd113_256x240.png b/sdncon/ui/static/css/thirdparty/images/ui-icons_fcd113_256x240.png
new file mode 100755
index 0000000..dd51951
--- /dev/null
+++ b/sdncon/ui/static/css/thirdparty/images/ui-icons_fcd113_256x240.png
Binary files differ
diff --git a/sdncon/ui/static/css/thirdparty/jquery-ui-1.10.2.custom.css b/sdncon/ui/static/css/thirdparty/jquery-ui-1.10.2.custom.css
new file mode 100755
index 0000000..bc07f1d
--- /dev/null
+++ b/sdncon/ui/static/css/thirdparty/jquery-ui-1.10.2.custom.css
@@ -0,0 +1,523 @@
+/*! jQuery UI - v1.10.2 - 2013-04-05
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.tabs.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helvetica%2CArial%2Csans-serif%3B&fwDefault=normal&fsDefault=14&cornerRadius=5px&bgColorHeader=%23e5e5e5&bgTextureHeader=flat&bgImgOpacityHeader=75&borderColorHeader=%23e5e5e5&fcHeader=%234d4d4f&iconColorHeader=%234d4d4f&bgColorContent=%23FFFFFF&bgTextureContent=flat&bgImgOpacityContent=100&borderColorContent=%23e5e5e5&fcContent=%234d4d4f&iconColorContent=%23f47d20&bgColorDefault=%23e5e5e5&bgTextureDefault=flat&bgImgOpacityDefault=45&borderColorDefault=%23e5e5e5&fcDefault=%234d4d4d&iconColorDefault=%234d4d4f&bgColorHover=%23e5e5e5&bgTextureHover=flat&bgImgOpacityHover=75&borderColorHover=%234d4d4f&fcHover=%23fdb813&iconColorHover=%23f47d20&bgColorActive=%23fdb813&bgTextureActive=flat&bgImgOpacityActive=50&borderColorActive=%23e5e5e5&fcActive=%23ffffff&iconColorActive=%23f47d20&bgColorHighlight=%23f8da4e&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=%23fcd113&fcHighlight=%23915608&iconColorHighlight=%23f7a50d&bgColorError=%23e14f1c&bgTextureError=gloss_wave&bgImgOpacityError=45&borderColorError=%23cd0a0a&fcError=%23ffffff&iconColorError=%23fcd113&bgColorOverlay=%23aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=75&opacityOverlay=30&bgColorShadow=%23999999&bgTextureShadow=flat&bgImgOpacityShadow=55&opacityShadow=45&thicknessShadow=0px&offsetTopShadow=5px&offsetLeftShadow=5px&cornerRadiusShadow=5px&tr%26ffDefault=Helvetica%2CArial%2Csans-serif
+* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden {
+	display: none;
+}
+.ui-helper-hidden-accessible {
+	border: 0;
+	clip: rect(0 0 0 0);
+	height: 1px;
+	margin: -1px;
+	overflow: hidden;
+	padding: 0;
+	position: absolute;
+	width: 1px;
+}
+.ui-helper-reset {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	outline: 0;
+	line-height: 1.3;
+	text-decoration: none;
+	font-size: 100%;
+	list-style: none;
+}
+.ui-helper-clearfix:before,
+.ui-helper-clearfix:after {
+	content: "";
+	display: table;
+	border-collapse: collapse;
+}
+.ui-helper-clearfix:after {
+	clear: both;
+}
+.ui-helper-clearfix {
+	min-height: 0; /* support: IE7 */
+}
+.ui-helper-zfix {
+	width: 100%;
+	height: 100%;
+	top: 0;
+	left: 0;
+	position: absolute;
+	opacity: 0;
+	filter:Alpha(Opacity=0);
+}
+
+.ui-front {
+	z-index: 100;
+}
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled {
+	cursor: default !important;
+}
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	display: block;
+	text-indent: -99999px;
+	overflow: hidden;
+	background-repeat: no-repeat;
+}
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay {
+	position: fixed;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+}
+.ui-tabs {
+	position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+	padding: .2em;
+}
+.ui-tabs .ui-tabs-nav {
+	margin: 0;
+	padding: .2em .2em 0;
+}
+.ui-tabs .ui-tabs-nav li {
+	list-style: none;
+	float: left;
+	position: relative;
+	top: 0;
+	margin: 1px .2em 0 0;
+	border-bottom-width: 0;
+	padding: 0;
+	white-space: nowrap;
+}
+.ui-tabs .ui-tabs-nav li a {
+	float: left;
+	padding: .5em 1em;
+	text-decoration: none;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active {
+	margin-bottom: -1px;
+	padding-bottom: 1px;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
+.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
+.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
+	cursor: text;
+}
+.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
+	cursor: pointer;
+}
+.ui-tabs .ui-tabs-panel {
+	display: block;
+	border-width: 0;
+	/*padding: 1em 1.4em;*/
+	background: none;
+}
+
+/* Component containers
+----------------------------------*/
+.ui-widget {
+	font-family: Helvetica,Arial,sans-serif;;
+	font-size: 14;
+}
+.ui-widget .ui-widget {
+	font-size: 1em;
+}
+.ui-widget input,
+.ui-widget select,
+.ui-widget textarea,
+.ui-widget button {
+	font-family: Helvetica,Arial,sans-serif;;
+	font-size: 1em;
+}
+.ui-widget-content {
+	/*border: 1px solid #e5e5e5;*/
+	background: #FFFFFF url(images/ui-bg_flat_100_FFFFFF_40x100.png) 50% 50% repeat-x;
+	color: #4d4d4f;
+}
+.ui-widget-content a {
+	color: #4d4d4f;
+}
+.ui-widget-header {
+	border: 1px solid #e5e5e5;
+	background: #e5e5e5 url(images/ui-bg_flat_75_e5e5e5_40x100.png) 50% 50% repeat-x;
+	color: #4d4d4f;
+	font-weight: bold;
+}
+.ui-widget-header a {
+	color: #4d4d4f;
+}
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default,
+.ui-widget-content .ui-state-default,
+.ui-widget-header .ui-state-default {
+	border: 1px solid #e5e5e5;
+	background: #e5e5e5 url(images/ui-bg_flat_45_e5e5e5_40x100.png) 50% 50% repeat-x;
+	font-weight: normal;
+	color: #4d4d4d;
+}
+.ui-state-default a,
+.ui-state-default a:link,
+.ui-state-default a:visited {
+	color: #4d4d4d;
+	text-decoration: none;
+}
+.ui-state-hover,
+.ui-widget-content .ui-state-hover,
+.ui-widget-header .ui-state-hover,
+.ui-state-focus,
+.ui-widget-content .ui-state-focus,
+.ui-widget-header .ui-state-focus {
+	border: 1px solid #4d4d4f;
+	background: #e5e5e5 url(images/ui-bg_flat_75_e5e5e5_40x100.png) 50% 50% repeat-x;
+	font-weight: normal;
+	color: #fdb813;
+}
+.ui-state-hover a,
+.ui-state-hover a:hover,
+.ui-state-hover a:link,
+.ui-state-hover a:visited {
+	color: #fdb813;
+	text-decoration: none;
+}
+.ui-state-active,
+.ui-widget-content .ui-state-active,
+.ui-widget-header .ui-state-active {
+	border: 1px solid #e5e5e5;
+	background: #fdb813 url(images/ui-bg_flat_50_fdb813_40x100.png) 50% 50% repeat-x;
+	font-weight: normal;
+	color: #ffffff;
+}
+.ui-state-active a,
+.ui-state-active a:link,
+.ui-state-active a:visited {
+	color: #ffffff;
+	text-decoration: none;
+}
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight,
+.ui-widget-content .ui-state-highlight,
+.ui-widget-header .ui-state-highlight {
+	border: 1px solid #fcd113;
+	background: #f8da4e url(images/ui-bg_glass_55_f8da4e_1x400.png) 50% 50% repeat-x;
+	color: #915608;
+}
+.ui-state-highlight a,
+.ui-widget-content .ui-state-highlight a,
+.ui-widget-header .ui-state-highlight a {
+	color: #915608;
+}
+.ui-state-error,
+.ui-widget-content .ui-state-error,
+.ui-widget-header .ui-state-error {
+	border: 1px solid #cd0a0a;
+	background: #e14f1c url(images/ui-bg_gloss-wave_45_e14f1c_500x100.png) 50% top repeat-x;
+	color: #ffffff;
+}
+.ui-state-error a,
+.ui-widget-content .ui-state-error a,
+.ui-widget-header .ui-state-error a {
+	color: #ffffff;
+}
+.ui-state-error-text,
+.ui-widget-content .ui-state-error-text,
+.ui-widget-header .ui-state-error-text {
+	color: #ffffff;
+}
+.ui-priority-primary,
+.ui-widget-content .ui-priority-primary,
+.ui-widget-header .ui-priority-primary {
+	font-weight: bold;
+}
+.ui-priority-secondary,
+.ui-widget-content .ui-priority-secondary,
+.ui-widget-header .ui-priority-secondary {
+	opacity: .7;
+	filter:Alpha(Opacity=70);
+	font-weight: normal;
+}
+.ui-state-disabled,
+.ui-widget-content .ui-state-disabled,
+.ui-widget-header .ui-state-disabled {
+	opacity: .35;
+	filter:Alpha(Opacity=35);
+	background-image: none;
+}
+.ui-state-disabled .ui-icon {
+	filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
+}
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	width: 16px;
+	height: 16px;
+}
+.ui-icon,
+.ui-widget-content .ui-icon {
+	background-image: url(images/ui-icons_f47d20_256x240.png);
+}
+.ui-widget-header .ui-icon {
+	background-image: url(images/ui-icons_4d4d4f_256x240.png);
+}
+.ui-state-default .ui-icon {
+	background-image: url(images/ui-icons_4d4d4f_256x240.png);
+}
+.ui-state-hover .ui-icon,
+.ui-state-focus .ui-icon {
+	background-image: url(images/ui-icons_f47d20_256x240.png);
+}
+.ui-state-active .ui-icon {
+	background-image: url(images/ui-icons_f47d20_256x240.png);
+}
+.ui-state-highlight .ui-icon {
+	background-image: url(images/ui-icons_f7a50d_256x240.png);
+}
+.ui-state-error .ui-icon,
+.ui-state-error-text .ui-icon {
+	background-image: url(images/ui-icons_fcd113_256x240.png);
+}
+
+/* positioning */
+.ui-icon-blank { background-position: 16px 16px; }
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-on { background-position: -96px -144px; }
+.ui-icon-radio-off { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-left,
+.ui-corner-tl {
+	border-top-left-radius: 5px;
+}
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-right,
+.ui-corner-tr {
+	border-top-right-radius: 5px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-left,
+.ui-corner-bl {
+/*	border-bottom-left-radius: 5px;*/
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-right,
+.ui-corner-br {
+/*	border-bottom-right-radius: 5px;*/
+}
+
+/* Overlays */
+.ui-widget-overlay {
+	background: #aaaaaa url(images/ui-bg_flat_75_aaaaaa_40x100.png) 50% 50% repeat-x;
+	opacity: .3;
+	filter: Alpha(Opacity=30);
+}
+.ui-widget-shadow {
+	margin: 5px 0 0 5px;
+	padding: 0px;
+	background: #999999 url(images/ui-bg_flat_55_999999_40x100.png) 50% 50% repeat-x;
+	opacity: .45;
+	filter: Alpha(Opacity=45);
+	border-radius: 5px;
+}
diff --git a/sdncon/ui/static/css/thirdparty/jquery-ui-1.10.2.custom.min.css b/sdncon/ui/static/css/thirdparty/jquery-ui-1.10.2.custom.min.css
new file mode 100755
index 0000000..b26eb9d
--- /dev/null
+++ b/sdncon/ui/static/css/thirdparty/jquery-ui-1.10.2.custom.min.css
@@ -0,0 +1,5 @@
+/*! jQuery UI - v1.10.2 - 2013-04-05
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.tabs.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helvetica%2CArial%2Csans-serif%3B&fwDefault=normal&fsDefault=14&cornerRadius=5px&bgColorHeader=%23e5e5e5&bgTextureHeader=flat&bgImgOpacityHeader=75&borderColorHeader=%23e5e5e5&fcHeader=%234d4d4f&iconColorHeader=%234d4d4f&bgColorContent=%23FFFFFF&bgTextureContent=flat&bgImgOpacityContent=100&borderColorContent=%23e5e5e5&fcContent=%234d4d4f&iconColorContent=%23f47d20&bgColorDefault=%23e5e5e5&bgTextureDefault=flat&bgImgOpacityDefault=45&borderColorDefault=%23e5e5e5&fcDefault=%234d4d4d&iconColorDefault=%234d4d4f&bgColorHover=%23e5e5e5&bgTextureHover=flat&bgImgOpacityHover=75&borderColorHover=%234d4d4f&fcHover=%23fdb813&iconColorHover=%23f47d20&bgColorActive=%23fdb813&bgTextureActive=flat&bgImgOpacityActive=50&borderColorActive=%23e5e5e5&fcActive=%23ffffff&iconColorActive=%23f47d20&bgColorHighlight=%23f8da4e&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=%23fcd113&fcHighlight=%23915608&iconColorHighlight=%23f7a50d&bgColorError=%23e14f1c&bgTextureError=gloss_wave&bgImgOpacityError=45&borderColorError=%23cd0a0a&fcError=%23ffffff&iconColorError=%23fcd113&bgColorOverlay=%23aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=75&opacityOverlay=30&bgColorShadow=%23999999&bgTextureShadow=flat&bgImgOpacityShadow=55&opacityShadow=45&thicknessShadow=0px&offsetTopShadow=5px&offsetLeftShadow=5px&cornerRadiusShadow=5px&tr%26ffDefault=Helvetica%2CArial%2Csans-serif
+* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav li a{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text}.ui-tabs .ui-tabs-nav li a,.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:0}.ui-widget{font-family:Helvetica,Arial,sans-serif;;font-size:14}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Helvetica,Arial,sans-serif;;font-size:1em}.ui-widget-content{border:1px solid #e5e5e5;background:#FFF url(images/ui-bg_flat_100_FFFFFF_40x100.png) 50% 50% repeat-x;color:#4d4d4f}.ui-widget-content a{color:#4d4d4f}.ui-widget-header{border:1px solid #e5e5e5;background:#e5e5e5 url(images/ui-bg_flat_75_e5e5e5_40x100.png) 50% 50% repeat-x;color:#4d4d4f;font-weight:bold}.ui-widget-header a{color:#4d4d4f}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #e5e5e5;background:#e5e5e5 url(images/ui-bg_flat_45_e5e5e5_40x100.png) 50% 50% repeat-x;font-weight:normal;color:#4d4d4d}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#4d4d4d;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #4d4d4f;background:#e5e5e5 url(images/ui-bg_flat_75_e5e5e5_40x100.png) 50% 50% repeat-x;font-weight:normal;color:#fdb813}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited{color:#fdb813;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #e5e5e5;background:#fdb813 url(images/ui-bg_flat_50_fdb813_40x100.png) 50% 50% repeat-x;font-weight:normal;color:#fff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#fff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcd113;background:#f8da4e url(images/ui-bg_glass_55_f8da4e_1x400.png) 50% 50% repeat-x;color:#915608}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#915608}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#e14f1c url(images/ui-bg_gloss-wave_45_e14f1c_500x100.png) 50% top repeat-x;color:#fff}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#fff}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#fff}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url(images/ui-icons_f47d20_256x240.png)}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_4d4d4f_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_4d4d4f_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_f47d20_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_f47d20_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_f7a50d_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_fcd113_256x240.png)}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:5px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:5px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:5px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:5px}.ui-widget-overlay{background:#aaa url(images/ui-bg_flat_75_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:5px 0 0 5px;padding:0;background:#999 url(images/ui-bg_flat_55_999999_40x100.png) 50% 50% repeat-x;opacity:.45;filter:Alpha(Opacity=45);border-radius:5px}
diff --git a/sdncon/ui/static/favicon.ico b/sdncon/ui/static/favicon.ico
new file mode 100755
index 0000000..6eee6ff
--- /dev/null
+++ b/sdncon/ui/static/favicon.ico
Binary files differ
diff --git a/sdncon/ui/static/images/logo_opendaylight.png b/sdncon/ui/static/images/logo_opendaylight.png
new file mode 100755
index 0000000..103520b
--- /dev/null
+++ b/sdncon/ui/static/images/logo_opendaylight.png
Binary files differ
diff --git a/sdncon/ui/static/images/refresh.png b/sdncon/ui/static/images/refresh.png
new file mode 100755
index 0000000..798cbf5
--- /dev/null
+++ b/sdncon/ui/static/images/refresh.png
Binary files differ
diff --git a/sdncon/ui/static/js/thirdparty/jit.js b/sdncon/ui/static/js/thirdparty/jit.js
new file mode 100755
index 0000000..9bf6e9e
--- /dev/null
+++ b/sdncon/ui/static/js/thirdparty/jit.js
@@ -0,0 +1,17163 @@
+/*
+Copyright (c) 2011 Sencha Inc. - Author: Nicolas Garcia Belmonte (http://philogb.github.com/)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+ */
+ (function () { 
+
+/*
+  File: Core.js
+
+ */
+
+/*
+ Object: $jit
+ 
+ Defines the namespace for all library Classes and Objects. 
+ This variable is the *only* global variable defined in the Toolkit. 
+ There are also other interesting properties attached to this variable described below.
+ */
+window.$jit = function(w) {
+  w = w || window;
+  for(var k in $jit) {
+    if($jit[k].$extend) {
+      w[k] = $jit[k];
+    }
+  }
+};
+
+$jit.version = '2.0.1';
+/*
+  Object: $jit.id
+  
+  Works just like *document.getElementById*
+  
+  Example:
+  (start code js)
+  var element = $jit.id('elementId');
+  (end code)
+
+*/
+
+/*
+ Object: $jit.util
+ 
+ Contains utility functions.
+ 
+ Some of the utility functions and the Class system were based in the MooTools Framework 
+ <http://mootools.net>. Copyright (c) 2006-2010 Valerio Proietti, <http://mad4milk.net/>. 
+ MIT license <http://mootools.net/license.txt>.
+ 
+ These methods are generally also implemented in DOM manipulation frameworks like JQuery, MooTools and Prototype.
+ I'd suggest you to use the functions from those libraries instead of using these, since their functions 
+ are widely used and tested in many different platforms/browsers. Use these functions only if you have to.
+ 
+ */
+var $ = function(d) {
+  return document.getElementById(d);
+};
+
+$.empty = function() {
+};
+
+/*
+  Method: extend
+  
+  Augment an object by appending another object's properties.
+  
+  Parameters:
+  
+  original - (object) The object to be extended.
+  extended - (object) An object which properties are going to be appended to the original object.
+  
+  Example:
+  (start code js)
+  $jit.util.extend({ 'a': 1, 'b': 2 }, { 'b': 3, 'c': 4 }); //{ 'a':1, 'b': 3, 'c': 4 }
+  (end code)
+*/
+$.extend = function(original, extended) {
+  for ( var key in (extended || {}))
+    original[key] = extended[key];
+  return original;
+};
+
+$.lambda = function(value) {
+  return (typeof value == 'function') ? value : function() {
+    return value;
+  };
+};
+
+$.time = Date.now || function() {
+  return +new Date;
+};
+
+/*
+  Method: splat
+  
+  Returns an array wrapping *obj* if *obj* is not an array. Returns *obj* otherwise.
+  
+  Parameters:
+  
+  obj - (mixed) The object to be wrapped in an array.
+  
+  Example:
+  (start code js)
+  $jit.util.splat(3);   //[3]
+  $jit.util.splat([3]); //[3]
+  (end code)
+*/
+$.splat = function(obj) {
+  var type = $.type(obj);
+  return type ? ((type != 'array') ? [ obj ] : obj) : [];
+};
+
+$.type = function(elem) {
+  var type = $.type.s.call(elem).match(/^\[object\s(.*)\]$/)[1].toLowerCase();
+  if(type != 'object') return type;
+  if(elem && elem.$$family) return elem.$$family;
+  return (elem && elem.nodeName && elem.nodeType == 1)? 'element' : type;
+};
+$.type.s = Object.prototype.toString;
+
+/*
+  Method: each
+  
+  Iterates through an iterable applying *f*.
+  
+  Parameters:
+  
+  iterable - (array) The original array.
+  fn - (function) The function to apply to the array elements.
+  
+  Example:
+  (start code js)
+  $jit.util.each([3, 4, 5], function(n) { alert('number ' + n); });
+  (end code)
+*/
+$.each = function(iterable, fn) {
+  var type = $.type(iterable);
+  if (type == 'object') {
+    for ( var key in iterable)
+      fn(iterable[key], key);
+  } else {
+    for ( var i = 0, l = iterable.length; i < l; i++)
+      fn(iterable[i], i);
+  }
+};
+
+$.indexOf = function(array, item) {
+  if(Array.indexOf) return array.indexOf(item);
+  for(var i=0,l=array.length; i<l; i++) {
+    if(array[i] === item) return i;
+  }
+  return -1;
+};
+
+/*
+  Method: map
+  
+  Maps or collects an array by applying *f*.
+  
+  Parameters:
+  
+  array - (array) The original array.
+  f - (function) The function to apply to the array elements.
+  
+  Example:
+  (start code js)
+  $jit.util.map([3, 4, 5], function(n) { return n*n; }); //[9, 16, 25]
+  (end code)
+*/
+$.map = function(array, f) {
+  var ans = [];
+  $.each(array, function(elem, i) {
+    ans.push(f(elem, i));
+  });
+  return ans;
+};
+
+/*
+  Method: reduce
+  
+  Iteratively applies the binary function *f* storing the result in an accumulator.
+  
+  Parameters:
+  
+  array - (array) The original array.
+  f - (function) The function to apply to the array elements.
+  opt - (optional|mixed) The starting value for the acumulator.
+  
+  Example:
+  (start code js)
+  $jit.util.reduce([3, 4, 5], function(x, y) { return x + y; }, 0); //12
+  (end code)
+*/
+$.reduce = function(array, f, opt) {
+  var l = array.length;
+  if(l==0) return opt;
+  var acum = arguments.length == 3? opt : array[--l];
+  while(l--) {
+    acum = f(acum, array[l]);
+  }
+  return acum;
+};
+
+/*
+  Method: merge
+  
+  Merges n-objects and their sub-objects creating a new, fresh object.
+  
+  Parameters:
+  
+  An arbitrary number of objects.
+  
+  Example:
+  (start code js)
+  $jit.util.merge({ 'a': 1, 'b': 2 }, { 'b': 3, 'c': 4 }); //{ 'a':1, 'b': 3, 'c': 4 }
+  (end code)
+*/
+$.merge = function() {
+  var mix = {};
+  for ( var i = 0, l = arguments.length; i < l; i++) {
+    var object = arguments[i];
+    if ($.type(object) != 'object')
+      continue;
+    for ( var key in object) {
+      var op = object[key], mp = mix[key];
+      mix[key] = (mp && $.type(op) == 'object' && $.type(mp) == 'object') ? $
+          .merge(mp, op) : $.unlink(op);
+    }
+  }
+  return mix;
+};
+
+$.unlink = function(object) {
+  var unlinked;
+  switch ($.type(object)) {
+  case 'object':
+    unlinked = {};
+    for ( var p in object)
+      unlinked[p] = $.unlink(object[p]);
+    break;
+  case 'array':
+    unlinked = [];
+    for ( var i = 0, l = object.length; i < l; i++)
+      unlinked[i] = $.unlink(object[i]);
+    break;
+  default:
+    return object;
+  }
+  return unlinked;
+};
+
+$.zip = function() {
+  if(arguments.length === 0) return [];
+  for(var j=0, ans=[], l=arguments.length, ml=arguments[0].length; j<ml; j++) {
+    for(var i=0, row=[]; i<l; i++) {
+      row.push(arguments[i][j]);
+    }
+    ans.push(row);
+  }
+  return ans;
+};
+
+/*
+  Method: rgbToHex
+  
+  Converts an RGB array into a Hex string.
+  
+  Parameters:
+  
+  srcArray - (array) An array with R, G and B values
+  
+  Example:
+  (start code js)
+  $jit.util.rgbToHex([255, 255, 255]); //'#ffffff'
+  (end code)
+*/
+$.rgbToHex = function(srcArray, array) {
+  if (srcArray.length < 3)
+    return null;
+  if (srcArray.length == 4 && srcArray[3] == 0 && !array)
+    return 'transparent';
+  var hex = [];
+  for ( var i = 0; i < 3; i++) {
+    var bit = (srcArray[i] - 0).toString(16);
+    hex.push(bit.length == 1 ? '0' + bit : bit);
+  }
+  return array ? hex : '#' + hex.join('');
+};
+
+/*
+  Method: hexToRgb
+  
+  Converts an Hex color string into an RGB array.
+  
+  Parameters:
+  
+  hex - (string) A color hex string.
+  
+  Example:
+  (start code js)
+  $jit.util.hexToRgb('#fff'); //[255, 255, 255]
+  (end code)
+*/
+$.hexToRgb = function(hex) {
+  if (hex.length != 7) {
+    hex = hex.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
+    hex.shift();
+    if (hex.length != 3)
+      return null;
+    var rgb = [];
+    for ( var i = 0; i < 3; i++) {
+      var value = hex[i];
+      if (value.length == 1)
+        value += value;
+      rgb.push(parseInt(value, 16));
+    }
+    return rgb;
+  } else {
+    hex = parseInt(hex.slice(1), 16);
+    return [ hex >> 16, hex >> 8 & 0xff, hex & 0xff ];
+  }
+};
+
+$.destroy = function(elem) {
+  $.clean(elem);
+  if (elem.parentNode)
+    elem.parentNode.removeChild(elem);
+  if (elem.clearAttributes)
+    elem.clearAttributes();
+};
+
+$.clean = function(elem) {
+  for (var ch = elem.childNodes, i = 0, l = ch.length; i < l; i++) {
+    $.destroy(ch[i]);
+  }
+};
+
+/*
+  Method: addEvent
+  
+  Cross-browser add event listener.
+  
+  Parameters:
+  
+  obj - (obj) The Element to attach the listener to.
+  type - (string) The listener type. For example 'click', or 'mousemove'.
+  fn - (function) The callback function to be used when the event is fired.
+  
+  Example:
+  (start code js)
+  $jit.util.addEvent(elem, 'click', function(){ alert('hello'); });
+  (end code)
+*/
+$.addEvent = function(obj, type, fn) {
+  if (obj.addEventListener)
+    obj.addEventListener(type, fn, false);
+  else
+    obj.attachEvent('on' + type, fn);
+};
+
+$.addEvents = function(obj, typeObj) {
+  for(var type in typeObj) {
+    $.addEvent(obj, type, typeObj[type]);
+  }
+};
+
+$.hasClass = function(obj, klass) {
+  return (' ' + obj.className + ' ').indexOf(' ' + klass + ' ') > -1;
+};
+
+$.addClass = function(obj, klass) {
+  if (!$.hasClass(obj, klass))
+    obj.className = (obj.className + " " + klass);
+};
+
+$.removeClass = function(obj, klass) {
+  obj.className = obj.className.replace(new RegExp(
+      '(^|\\s)' + klass + '(?:\\s|$)'), '$1');
+};
+
+$.getPos = function(elem) {
+  var offset = getOffsets(elem);
+  var scroll = getScrolls(elem);
+  return {
+    x: offset.x - scroll.x,
+    y: offset.y - scroll.y
+  };
+
+  function getOffsets(elem) {
+    var position = {
+      x: 0,
+      y: 0
+    };
+    while (elem && !isBody(elem)) {
+      position.x += elem.offsetLeft;
+      position.y += elem.offsetTop;
+      elem = elem.offsetParent;
+    }
+    return position;
+  }
+
+  function getScrolls(elem) {
+    var position = {
+      x: 0,
+      y: 0
+    };
+    while (elem && !isBody(elem)) {
+      position.x += elem.scrollLeft;
+      position.y += elem.scrollTop;
+      elem = elem.parentNode;
+    }
+    return position;
+  }
+
+  function isBody(element) {
+    return (/^(?:body|html)$/i).test(element.tagName);
+  }
+};
+
+$.event = {
+  get: function(e, win) {
+    win = win || window;
+    return e || win.event;
+  },
+  getWheel: function(e) {
+    return e.wheelDelta? e.wheelDelta / 120 : -(e.detail || 0) / 3;
+  },
+  isRightClick: function(e) {
+    return (e.which == 3 || e.button == 2);
+  },
+  getPos: function(e, win) {
+    // get mouse position
+    win = win || window;
+    e = e || win.event;
+    var doc = win.document;
+    doc = doc.documentElement || doc.body;
+    //TODO(nico): make touch event handling better
+    if(e.touches && e.touches.length) {
+      e = e.touches[0];
+    }
+    var page = {
+      x: e.pageX || (e.clientX + doc.scrollLeft),
+      y: e.pageY || (e.clientY + doc.scrollTop)
+    };
+    return page;
+  },
+  stop: function(e) {
+    if (e.stopPropagation) e.stopPropagation();
+    e.cancelBubble = true;
+    if (e.preventDefault) e.preventDefault();
+    else e.returnValue = false;
+  }
+};
+
+$jit.util = $jit.id = $;
+
+var Class = function(properties) {
+  properties = properties || {};
+  var klass = function() {
+    for ( var key in this) {
+      if (typeof this[key] != 'function')
+        this[key] = $.unlink(this[key]);
+    }
+    this.constructor = klass;
+    if (Class.prototyping)
+      return this;
+    var instance = this.initialize ? this.initialize.apply(this, arguments)
+        : this;
+    //typize
+    this.$$family = 'class';
+    return instance;
+  };
+
+  for ( var mutator in Class.Mutators) {
+    if (!properties[mutator])
+      continue;
+    properties = Class.Mutators[mutator](properties, properties[mutator]);
+    delete properties[mutator];
+  }
+
+  $.extend(klass, this);
+  klass.constructor = Class;
+  klass.prototype = properties;
+  return klass;
+};
+
+Class.Mutators = {
+
+  Implements: function(self, klasses) {
+    $.each($.splat(klasses), function(klass) {
+      Class.prototyping = klass;
+      var instance = (typeof klass == 'function') ? new klass : klass;
+      for ( var prop in instance) {
+        if (!(prop in self)) {
+          self[prop] = instance[prop];
+        }
+      }
+      delete Class.prototyping;
+    });
+    return self;
+  }
+
+};
+
+$.extend(Class, {
+
+  inherit: function(object, properties) {
+    for ( var key in properties) {
+      var override = properties[key];
+      var previous = object[key];
+      var type = $.type(override);
+      if (previous && type == 'function') {
+        if (override != previous) {
+          Class.override(object, key, override);
+        }
+      } else if (type == 'object') {
+        object[key] = $.merge(previous, override);
+      } else {
+        object[key] = override;
+      }
+    }
+    return object;
+  },
+
+  override: function(object, name, method) {
+    var parent = Class.prototyping;
+    if (parent && object[name] != parent[name])
+      parent = null;
+    var override = function() {
+      var previous = this.parent;
+      this.parent = parent ? parent[name] : object[name];
+      var value = method.apply(this, arguments);
+      this.parent = previous;
+      return value;
+    };
+    object[name] = override;
+  }
+
+});
+
+Class.prototype.implement = function() {
+  var proto = this.prototype;
+  $.each(Array.prototype.slice.call(arguments || []), function(properties) {
+    Class.inherit(proto, properties);
+  });
+  return this;
+};
+
+$jit.Class = Class;
+
+/*
+  Object: $jit.json
+  
+  Provides JSON utility functions.
+  
+  Most of these functions are JSON-tree traversal and manipulation functions.
+*/
+$jit.json = {
+  /*
+     Method: prune
+  
+     Clears all tree nodes having depth greater than maxLevel.
+  
+     Parameters:
+  
+        tree - (object) A JSON tree object. For more information please see <Loader.loadJSON>.
+        maxLevel - (number) An integer specifying the maximum level allowed for this tree. All nodes having depth greater than max level will be deleted.
+
+  */
+  prune: function(tree, maxLevel) {
+    this.each(tree, function(elem, i) {
+      if (i == maxLevel && elem.children) {
+        delete elem.children;
+        elem.children = [];
+      }
+    });
+  },
+  /*
+     Method: getParent
+  
+     Returns the parent node of the node having _id_ as id.
+  
+     Parameters:
+  
+        tree - (object) A JSON tree object. See also <Loader.loadJSON>.
+        id - (string) The _id_ of the child node whose parent will be returned.
+
+    Returns:
+
+        A tree JSON node if any, or false otherwise.
+  
+  */
+  getParent: function(tree, id) {
+    if (tree.id == id)
+      return false;
+    var ch = tree.children;
+    if (ch && ch.length > 0) {
+      for ( var i = 0; i < ch.length; i++) {
+        if (ch[i].id == id)
+          return tree;
+        else {
+          var ans = this.getParent(ch[i], id);
+          if (ans)
+            return ans;
+        }
+      }
+    }
+    return false;
+  },
+  /*
+     Method: getSubtree
+  
+     Returns the subtree that matches the given id.
+  
+     Parameters:
+  
+        tree - (object) A JSON tree object. See also <Loader.loadJSON>.
+        id - (string) A node *unique* identifier.
+  
+     Returns:
+  
+        A subtree having a root node matching the given id. Returns null if no subtree matching the id is found.
+
+  */
+  getSubtree: function(tree, id) {
+    if (tree.id == id)
+      return tree;
+    for ( var i = 0, ch = tree.children; ch && i < ch.length; i++) {
+      var t = this.getSubtree(ch[i], id);
+      if (t != null)
+        return t;
+    }
+    return null;
+  },
+  /*
+     Method: eachLevel
+  
+      Iterates on tree nodes with relative depth less or equal than a specified level.
+  
+     Parameters:
+  
+        tree - (object) A JSON tree or subtree. See also <Loader.loadJSON>.
+        initLevel - (number) An integer specifying the initial relative level. Usually zero.
+        toLevel - (number) An integer specifying a top level. This method will iterate only through nodes with depth less than or equal this number.
+        action - (function) A function that receives a node and an integer specifying the actual level of the node.
+          
+    Example:
+   (start code js)
+     $jit.json.eachLevel(tree, 0, 3, function(node, depth) {
+        alert(node.name + ' ' + depth);
+     });
+   (end code)
+  */
+  eachLevel: function(tree, initLevel, toLevel, action) {
+    if (initLevel <= toLevel) {
+      action(tree, initLevel);
+      if(!tree.children) return;
+      for ( var i = 0, ch = tree.children; i < ch.length; i++) {
+        this.eachLevel(ch[i], initLevel + 1, toLevel, action);
+      }
+    }
+  },
+  /*
+     Method: each
+  
+      A JSON tree iterator.
+  
+     Parameters:
+  
+        tree - (object) A JSON tree or subtree. See also <Loader.loadJSON>.
+        action - (function) A function that receives a node.
+
+    Example:
+    (start code js)
+      $jit.json.each(tree, function(node) {
+        alert(node.name);
+      });
+    (end code)
+          
+  */
+  each: function(tree, action) {
+    this.eachLevel(tree, 0, Number.MAX_VALUE, action);
+  }
+};
+
+
+/*
+     An object containing multiple type of transformations. 
+*/
+
+$jit.Trans = {
+  $extend: true,
+  
+  linear: function(p){
+    return p;
+  }
+};
+
+var Trans = $jit.Trans;
+
+(function(){
+
+  var makeTrans = function(transition, params){
+    params = $.splat(params);
+    return $.extend(transition, {
+      easeIn: function(pos){
+        return transition(pos, params);
+      },
+      easeOut: function(pos){
+        return 1 - transition(1 - pos, params);
+      },
+      easeInOut: function(pos){
+        return (pos <= 0.5)? transition(2 * pos, params) / 2 : (2 - transition(
+            2 * (1 - pos), params)) / 2;
+      }
+    });
+  };
+
+  var transitions = {
+
+    Pow: function(p, x){
+      return Math.pow(p, x[0] || 6);
+    },
+
+    Expo: function(p){
+      return Math.pow(2, 8 * (p - 1));
+    },
+
+    Circ: function(p){
+      return 1 - Math.sin(Math.acos(p));
+    },
+
+    Sine: function(p){
+      return 1 - Math.sin((1 - p) * Math.PI / 2);
+    },
+
+    Back: function(p, x){
+      x = x[0] || 1.618;
+      return Math.pow(p, 2) * ((x + 1) * p - x);
+    },
+
+    Bounce: function(p){
+      var value;
+      for ( var a = 0, b = 1; 1; a += b, b /= 2) {
+        if (p >= (7 - 4 * a) / 11) {
+          value = b * b - Math.pow((11 - 6 * a - 11 * p) / 4, 2);
+          break;
+        }
+      }
+      return value;
+    },
+
+    Elastic: function(p, x){
+      return Math.pow(2, 10 * --p)
+          * Math.cos(20 * p * Math.PI * (x[0] || 1) / 3);
+    }
+
+  };
+
+  $.each(transitions, function(val, key){
+    Trans[key] = makeTrans(val);
+  });
+
+  $.each( [
+      'Quad', 'Cubic', 'Quart', 'Quint'
+  ], function(elem, i){
+    Trans[elem] = makeTrans(function(p){
+      return Math.pow(p, [
+        i + 2
+      ]);
+    });
+  });
+
+})();
+
+/*
+   A Class that can perform animations for generic objects.
+
+   If you are looking for animation transitions please take a look at the <Trans> object.
+
+   Used by:
+
+   <Graph.Plot>
+   
+   Based on:
+   
+   The Animation class is based in the MooTools Framework <http://mootools.net>. Copyright (c) 2006-2009 Valerio Proietti, <http://mad4milk.net/>. MIT license <http://mootools.net/license.txt>.
+
+*/
+
+var Animation = new Class( {
+
+  initialize: function(options){
+    this.setOptions(options);
+  },
+
+  setOptions: function(options){
+    var opt = {
+      duration: 2500,
+      fps: 40,
+      transition: Trans.Quart.easeInOut,
+      compute: $.empty,
+      complete: $.empty,
+      link: 'ignore'
+    };
+    this.opt = $.merge(opt, options || {});
+    return this;
+  },
+
+  step: function(){
+    var time = $.time(), opt = this.opt;
+    if (time < this.time + opt.duration) {
+      var delta = opt.transition((time - this.time) / opt.duration);
+      opt.compute(delta);
+    } else {
+      this.timer = clearInterval(this.timer);
+      opt.compute(1);
+      opt.complete();
+    }
+  },
+
+  start: function(){
+    if (!this.check())
+      return this;
+    this.time = 0;
+    this.startTimer();
+    return this;
+  },
+
+  startTimer: function(){
+    var that = this, fps = this.opt.fps;
+    if (this.timer)
+      return false;
+    this.time = $.time() - this.time;
+    this.timer = setInterval((function(){
+      that.step();
+    }), Math.round(1000 / fps));
+    return true;
+  },
+
+  pause: function(){
+    this.stopTimer();
+    return this;
+  },
+
+  resume: function(){
+    this.startTimer();
+    return this;
+  },
+
+  stopTimer: function(){
+    if (!this.timer)
+      return false;
+    this.time = $.time() - this.time;
+    this.timer = clearInterval(this.timer);
+    return true;
+  },
+
+  check: function(){
+    if (!this.timer)
+      return true;
+    if (this.opt.link == 'cancel') {
+      this.stopTimer();
+      return true;
+    }
+    return false;
+  }
+});
+
+
+var Options = function() {
+  var args = arguments;
+  for(var i=0, l=args.length, ans={}; i<l; i++) {
+    var opt = Options[args[i]];
+    if(opt.$extend) {
+      $.extend(ans, opt);
+    } else {
+      ans[args[i]] = opt;  
+    }
+  }
+  return ans;
+};
+
+/*
+ * File: Options.AreaChart.js
+ *
+*/
+
+/*
+  Object: Options.AreaChart
+  
+  <AreaChart> options. 
+  Other options included in the AreaChart are <Options.Canvas>, <Options.Label>, <Options.Margin>, <Options.Tips> and <Options.Events>.
+  
+  Syntax:
+  
+  (start code js)
+
+  Options.AreaChart = {
+    animate: true,
+    labelOffset: 3,
+    type: 'stacked',
+    selectOnHover: true,
+    showAggregates: true,
+    showLabels: true,
+    filterOnClick: false,
+    restoreOnRightClick: false
+  };
+  
+  (end code)
+  
+  Example:
+  
+  (start code js)
+
+  var areaChart = new $jit.AreaChart({
+    animate: true,
+    type: 'stacked:gradient',
+    selectOnHover: true,
+    filterOnClick: true,
+    restoreOnRightClick: true
+  });
+  
+  (end code)
+
+  Parameters:
+  
+  animate - (boolean) Default's *true*. Whether to add animated transitions when filtering/restoring stacks.
+  labelOffset - (number) Default's *3*. Adds margin between the label and the default place where it should be drawn.
+  type - (string) Default's *'stacked'*. Stack style. Posible values are 'stacked', 'stacked:gradient' to add gradients.
+  selectOnHover - (boolean) Default's *true*. If true, it will add a mark to the hovered stack.
+  showAggregates - (boolean, function) Default's *true*. Display the values of the stacks. Can also be a function that returns *true* or *false* to display or filter some values. That same function can also return a string with the formatted value.
+  showLabels - (boolean, function) Default's *true*. Display the name of the slots. Can also be a function that returns *true* or *false* to display or not each label.
+  filterOnClick - (boolean) Default's *true*. Select the clicked stack by hiding all other stacks.
+  restoreOnRightClick - (boolean) Default's *true*. Show all stacks by right clicking.
+  
+*/
+  
+Options.AreaChart = {
+  $extend: true,
+
+  animate: true,
+  labelOffset: 3, // label offset
+  type: 'stacked', // gradient
+  Tips: {
+    enable: false,
+    onShow: $.empty,
+    onHide: $.empty
+  },
+  Events: {
+    enable: false,
+    onClick: $.empty
+  },
+  selectOnHover: true,
+  showAggregates: true,
+  showLabels: true,
+  filterOnClick: false,
+  restoreOnRightClick: false
+};
+
+/*
+ * File: Options.Margin.js
+ *
+*/
+
+/*
+  Object: Options.Margin
+  
+  Canvas drawing margins. 
+  
+  Syntax:
+  
+  (start code js)
+
+  Options.Margin = {
+    top: 0,
+    left: 0,
+    right: 0,
+    bottom: 0
+  };
+  
+  (end code)
+  
+  Example:
+  
+  (start code js)
+
+  var viz = new $jit.Viz({
+    Margin: {
+      right: 10,
+      bottom: 20
+    }
+  });
+  
+  (end code)
+
+  Parameters:
+  
+  top - (number) Default's *0*. Top margin.
+  left - (number) Default's *0*. Left margin.
+  right - (number) Default's *0*. Right margin.
+  bottom - (number) Default's *0*. Bottom margin.
+  
+*/
+
+Options.Margin = {
+  $extend: false,
+  
+  top: 0,
+  left: 0,
+  right: 0,
+  bottom: 0
+};
+
+/*
+ * File: Options.Canvas.js
+ *
+*/
+
+/*
+  Object: Options.Canvas
+  
+  These are Canvas general options, like where to append it in the DOM, its dimensions, background, 
+  and other more advanced options.
+  
+  Syntax:
+  
+  (start code js)
+
+  Options.Canvas = {
+    injectInto: 'id',
+    type: '2D', //'3D'
+    width: false,
+    height: false,
+    useCanvas: false,
+    withLabels: true,
+    background: false
+  };  
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var viz = new $jit.Viz({
+    injectInto: 'someContainerId',
+    width: 500,
+    height: 700
+  });
+  (end code)
+  
+  Parameters:
+  
+  injectInto - *required* (string|element) The id of the DOM container for the visualization. It can also be an Element provided that it has an id.
+  type - (string) Context type. Default's 2D but can be 3D for webGL enabled browsers.
+  width - (number) Default's to the *container's offsetWidth*. The width of the canvas.
+  height - (number) Default's to the *container's offsetHeight*. The height of the canvas.
+  useCanvas - (boolean|object) Default's *false*. You can pass another <Canvas> instance to be used by the visualization.
+  withLabels - (boolean) Default's *true*. Whether to use a label container for the visualization.
+  background - (boolean|object) Default's *false*. An object containing information about the rendering of a background canvas.
+*/
+
+Options.Canvas = {
+    $extend: true,
+    
+    injectInto: 'id',
+    type: '2D',
+    width: false,
+    height: false,
+    useCanvas: false,
+    withLabels: true,
+    background: false,
+    
+    Scene: {
+      Lighting: {
+        enable: false,
+        ambient: [1, 1, 1],
+        directional: {
+          direction: { x: -100, y: -100, z: -100 },
+          color: [0.5, 0.3, 0.1]
+        }
+      }
+    }
+};
+
+/*
+ * File: Options.Tree.js
+ *
+*/
+
+/*
+  Object: Options.Tree
+  
+  Options related to (strict) Tree layout algorithms. These options are used by the <ST> visualization.
+  
+  Syntax:
+  
+  (start code js)
+  Options.Tree = {
+    orientation: "left",
+    subtreeOffset: 8,
+    siblingOffset: 5,
+    indent:10,
+    multitree: false,
+    align:"center"
+  };
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var st = new $jit.ST({
+    orientation: 'left',
+    subtreeOffset: 1,
+    siblingOFfset: 5,
+    multitree: true
+  });
+  (end code)
+
+  Parameters:
+    
+  subtreeOffset - (number) Default's 8. Separation offset between subtrees.
+  siblingOffset - (number) Default's 5. Separation offset between siblings.
+  orientation - (string) Default's 'left'. Tree orientation layout. Possible values are 'left', 'top', 'right', 'bottom'.
+  align - (string) Default's *center*. Whether the tree alignment is 'left', 'center' or 'right'.
+  indent - (number) Default's 10. Used when *align* is left or right and shows an indentation between parent and children.
+  multitree - (boolean) Default's *false*. Used with the node $orn data property for creating multitrees.
+     
+*/
+Options.Tree = {
+    $extend: true,
+    
+    orientation: "left",
+    subtreeOffset: 8,
+    siblingOffset: 5,
+    indent:10,
+    multitree: false,
+    align:"center"
+};
+
+
+/*
+ * File: Options.Node.js
+ *
+*/
+
+/*
+  Object: Options.Node
+
+  Provides Node rendering options for Tree and Graph based visualizations.
+
+  Syntax:
+    
+  (start code js)
+  Options.Node = {
+    overridable: false,
+    type: 'circle',
+    color: '#ccb',
+    alpha: 1,
+    dim: 3,
+    height: 20,
+    width: 90,
+    autoHeight: false,
+    autoWidth: false,
+    lineWidth: 1,
+    transform: true,
+    align: "center",
+    angularWidth:1,
+    span:1,
+    CanvasStyles: {}
+  };
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var viz = new $jit.Viz({
+    Node: {
+      overridable: true,
+      width: 30,
+      autoHeight: true,
+      type: 'rectangle'
+    }
+  });
+  (end code)
+  
+  Parameters:
+
+  overridable - (boolean) Default's *false*. Determine whether or not general node properties can be overridden by a particular <Graph.Node>.
+  type - (string) Default's *circle*. Node's shape. Node built-in types include 'circle', 'rectangle', 'square', 'ellipse', 'triangle', 'star'. The default Node type might vary in each visualization. You can also implement (non built-in) custom Node types into your visualizations.
+  color - (string) Default's *#ccb*. Node color.
+  alpha - (number) Default's *1*. The Node's alpha value. *1* is for full opacity.
+  dim - (number) Default's *3*. An extra parameter used by 'circle', 'square', 'triangle' and 'star' node types. Depending on each shape, this parameter can set the radius of a circle, half the length of the side of a square, half the base and half the height of a triangle or the length of a side of a star (concave decagon).
+  height - (number) Default's *20*. Used by 'rectangle' and 'ellipse' node types. The height of the node shape.
+  width - (number) Default's *90*. Used by 'rectangle' and 'ellipse' node types. The width of the node shape.
+  autoHeight - (boolean) Default's *false*. Whether to set an auto height for the node depending on the content of the Node's label.
+  autoWidth - (boolean) Default's *false*. Whether to set an auto width for the node depending on the content of the Node's label.
+  lineWidth - (number) Default's *1*. Used only by some Node shapes. The line width of the strokes of a node.
+  transform - (boolean) Default's *true*. Only used by the <Hypertree> visualization. Whether to scale the nodes according to the moebius transformation.
+  align - (string) Default's *center*. Possible values are 'center', 'left' or 'right'. Used only by the <ST> visualization, these parameters are used for aligning nodes when some of they dimensions vary.
+  angularWidth - (number) Default's *1*. Used in radial layouts (like <RGraph> or <Sunburst> visualizations). The amount of relative 'space' set for a node.
+  span - (number) Default's *1*. Used in radial layouts (like <RGraph> or <Sunburst> visualizations). The angle span amount set for a node.
+  CanvasStyles - (object) Default's an empty object (i.e. {}). Attach any other canvas specific property that you'd set to the canvas context before plotting a Node.
+
+*/
+Options.Node = {
+  $extend: false,
+  
+  overridable: false,
+  type: 'circle',
+  color: '#ccb',
+  alpha: 1,
+  dim: 3,
+  height: 20,
+  width: 90,
+  autoHeight: false,
+  autoWidth: false,
+  lineWidth: 1,
+  transform: true,
+  align: "center",
+  angularWidth:1,
+  span:1,
+  //Raw canvas styles to be
+  //applied to the context instance
+  //before plotting a node
+  CanvasStyles: {}
+};
+
+
+/*
+ * File: Options.Edge.js
+ *
+*/
+
+/*
+  Object: Options.Edge
+
+  Provides Edge rendering options for Tree and Graph based visualizations.
+
+  Syntax:
+    
+  (start code js)
+  Options.Edge = {
+    overridable: false,
+    type: 'line',
+    color: '#ccb',
+    lineWidth: 1,
+    dim:15,
+    alpha: 1,
+    CanvasStyles: {}
+  };
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var viz = new $jit.Viz({
+    Edge: {
+      overridable: true,
+      type: 'line',
+      color: '#fff',
+      CanvasStyles: {
+        shadowColor: '#ccc',
+        shadowBlur: 10
+      }
+    }
+  });
+  (end code)
+  
+  Parameters:
+    
+   overridable - (boolean) Default's *false*. Determine whether or not general edges properties can be overridden by a particular <Graph.Adjacence>.
+   type - (string) Default's 'line'. Edge styles include 'line', 'hyperline', 'arrow'. The default Edge type might vary in each visualization. You can also implement custom Edge types.
+   color - (string) Default's '#ccb'. Edge color.
+   lineWidth - (number) Default's *1*. Line/Edge width.
+   alpha - (number) Default's *1*. The Edge's alpha value. *1* is for full opacity.
+   dim - (number) Default's *15*. An extra parameter used by other complex shapes such as quadratic, bezier or arrow, to determine the shape's diameter.
+   epsilon - (number) Default's *7*. Only used when using *enableForEdges* in <Options.Events>. This dimension is used to create an area for the line where the contains method for the edge returns *true*.
+   CanvasStyles - (object) Default's an empty object (i.e. {}). Attach any other canvas specific property that you'd set to the canvas context before plotting an Edge.
+
+  See also:
+   
+   If you want to know more about how to customize Node/Edge data per element, in the JSON or programmatically, take a look at this article.
+*/
+Options.Edge = {
+  $extend: false,
+  
+  overridable: false,
+  type: 'line',
+  color: '#ccb',
+  lineWidth: 1,
+  dim:15,
+  alpha: 1,
+  epsilon: 7,
+
+  //Raw canvas styles to be
+  //applied to the context instance
+  //before plotting an edge
+  CanvasStyles: {}
+};
+
+
+/*
+ * File: Options.Fx.js
+ *
+*/
+
+/*
+  Object: Options.Fx
+
+  Provides animation options like duration of the animations, frames per second and animation transitions.  
+
+  Syntax:
+  
+  (start code js)
+    Options.Fx = {
+      fps:40,
+      duration: 2500,
+      transition: $jit.Trans.Quart.easeInOut,
+      clearCanvas: true
+    };
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var viz = new $jit.Viz({
+    duration: 1000,
+    fps: 35,
+    transition: $jit.Trans.linear
+  });
+  (end code)
+  
+  Parameters:
+  
+  clearCanvas - (boolean) Default's *true*. Whether to clear the frame/canvas when the viz is plotted or animated.
+  duration - (number) Default's *2500*. Duration of the animation in milliseconds.
+  fps - (number) Default's *40*. Frames per second.
+  transition - (object) Default's *$jit.Trans.Quart.easeInOut*. The transition used for the animations. See below for a more detailed explanation.
+  
+  Object: $jit.Trans
+  
+  This object is used for specifying different animation transitions in all visualizations.
+
+  There are many different type of animation transitions.
+
+  linear:
+
+  Displays a linear transition
+
+  >Trans.linear
+  
+  (see Linear.png)
+
+  Quad:
+
+  Displays a Quadratic transition.
+
+  >Trans.Quad.easeIn
+  >Trans.Quad.easeOut
+  >Trans.Quad.easeInOut
+  
+ (see Quad.png)
+
+ Cubic:
+
+ Displays a Cubic transition.
+
+ >Trans.Cubic.easeIn
+ >Trans.Cubic.easeOut
+ >Trans.Cubic.easeInOut
+
+ (see Cubic.png)
+
+ Quart:
+
+ Displays a Quartetic transition.
+
+ >Trans.Quart.easeIn
+ >Trans.Quart.easeOut
+ >Trans.Quart.easeInOut
+
+ (see Quart.png)
+
+ Quint:
+
+ Displays a Quintic transition.
+
+ >Trans.Quint.easeIn
+ >Trans.Quint.easeOut
+ >Trans.Quint.easeInOut
+
+ (see Quint.png)
+
+ Expo:
+
+ Displays an Exponential transition.
+
+ >Trans.Expo.easeIn
+ >Trans.Expo.easeOut
+ >Trans.Expo.easeInOut
+
+ (see Expo.png)
+
+ Circ:
+
+ Displays a Circular transition.
+
+ >Trans.Circ.easeIn
+ >Trans.Circ.easeOut
+ >Trans.Circ.easeInOut
+
+ (see Circ.png)
+
+ Sine:
+
+ Displays a Sineousidal transition.
+
+ >Trans.Sine.easeIn
+ >Trans.Sine.easeOut
+ >Trans.Sine.easeInOut
+
+ (see Sine.png)
+
+ Back:
+
+ >Trans.Back.easeIn
+ >Trans.Back.easeOut
+ >Trans.Back.easeInOut
+
+ (see Back.png)
+
+ Bounce:
+
+ Bouncy transition.
+
+ >Trans.Bounce.easeIn
+ >Trans.Bounce.easeOut
+ >Trans.Bounce.easeInOut
+
+ (see Bounce.png)
+
+ Elastic:
+
+ Elastic curve.
+
+ >Trans.Elastic.easeIn
+ >Trans.Elastic.easeOut
+ >Trans.Elastic.easeInOut
+
+ (see Elastic.png)
+ 
+ Based on:
+     
+ Easing and Transition animation methods are based in the MooTools Framework <http://mootools.net>. Copyright (c) 2006-2010 Valerio Proietti, <http://mad4milk.net/>. MIT license <http://mootools.net/license.txt>.
+
+
+*/
+Options.Fx = {
+  $extend: true,
+  
+  fps:40,
+  duration: 2500,
+  transition: $jit.Trans.Quart.easeInOut,
+  clearCanvas: true
+};
+
+/*
+ * File: Options.Label.js
+ *
+*/
+/*
+  Object: Options.Label
+
+  Provides styling for Labels such as font size, family, etc. Also sets Node labels as HTML, SVG or Native canvas elements.  
+
+  Syntax:
+  
+  (start code js)
+    Options.Label = {
+      overridable: false,
+      type: 'HTML', //'SVG', 'Native'
+      style: ' ',
+      size: 10,
+      family: 'sans-serif',
+      textAlign: 'center',
+      textBaseline: 'alphabetic',
+      color: '#fff'
+    };
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var viz = new $jit.Viz({
+    Label: {
+      type: 'Native',
+      size: 11,
+      color: '#ccc'
+    }
+  });
+  (end code)
+  
+  Parameters:
+    
+  overridable - (boolean) Default's *false*. Determine whether or not general label properties can be overridden by a particular <Graph.Node>.
+  type - (string) Default's *HTML*. The type for the labels. Can be 'HTML', 'SVG' or 'Native' canvas labels.
+  style - (string) Default's *empty string*. Can be 'italic' or 'bold'. This parameter is only taken into account when using 'Native' canvas labels. For DOM based labels the className *node* is added to the DOM element for styling via CSS. You can also use <Options.Controller> methods to style individual labels.
+  size - (number) Default's *10*. The font's size. This parameter is only taken into account when using 'Native' canvas labels. For DOM based labels the className *node* is added to the DOM element for styling via CSS. You can also use <Options.Controller> methods to style individual labels.
+  family - (string) Default's *sans-serif*. The font's family. This parameter is only taken into account when using 'Native' canvas labels. For DOM based labels the className *node* is added to the DOM element for styling via CSS. You can also use <Options.Controller> methods to style individual labels.
+  color - (string) Default's *#fff*. The font's color. This parameter is only taken into account when using 'Native' canvas labels. For DOM based labels the className *node* is added to the DOM element for styling via CSS. You can also use <Options.Controller> methods to style individual labels.
+*/
+Options.Label = {
+  $extend: false,
+  
+  overridable: false,
+  type: 'HTML', //'SVG', 'Native'
+  style: ' ',
+  size: 10,
+  family: 'sans-serif',
+  textAlign: 'center',
+  textBaseline: 'alphabetic',
+  color: '#fff'
+};
+
+
+/*
+ * File: Options.Tips.js
+ *
+ */
+
+/*
+  Object: Options.Tips
+  
+  Tips options
+  
+  Syntax:
+    
+  (start code js)
+  Options.Tips = {
+    enable: false,
+    type: 'auto',
+    offsetX: 20,
+    offsetY: 20,
+    onShow: $.empty,
+    onHide: $.empty
+  };
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var viz = new $jit.Viz({
+    Tips: {
+      enable: true,
+      type: 'Native',
+      offsetX: 10,
+      offsetY: 10,
+      onShow: function(tip, node) {
+        tip.innerHTML = node.name;
+      }
+    }
+  });
+  (end code)
+
+  Parameters:
+
+  enable - (boolean) Default's *false*. If *true*, a tooltip will be shown when a node is hovered. The tooltip is a div DOM element having "tip" as CSS class. 
+  type - (string) Default's *auto*. Defines where to attach the MouseEnter/Leave tooltip events. Possible values are 'Native' to attach them to the canvas or 'HTML' to attach them to DOM label elements (if defined). 'auto' sets this property to the value of <Options.Label>'s *type* property.
+  offsetX - (number) Default's *20*. An offset added to the current tooltip x-position (which is the same as the current mouse position). Default's 20.
+  offsetY - (number) Default's *20*. An offset added to the current tooltip y-position (which is the same as the current mouse position). Default's 20.
+  onShow(tip, node) - This callack is used right before displaying a tooltip. The first formal parameter is the tip itself (which is a DivElement). The second parameter may be a <Graph.Node> for graph based visualizations or an object with label, value properties for charts.
+  onHide() - This callack is used when hiding a tooltip.
+
+*/
+Options.Tips = {
+  $extend: false,
+  
+  enable: false,
+  type: 'auto',
+  offsetX: 20,
+  offsetY: 20,
+  force: false,
+  onShow: $.empty,
+  onHide: $.empty
+};
+
+
+/*
+ * File: Options.NodeStyles.js
+ *
+ */
+
+/*
+  Object: Options.NodeStyles
+  
+  Apply different styles when a node is hovered or selected.
+  
+  Syntax:
+    
+  (start code js)
+  Options.NodeStyles = {
+    enable: false,
+    type: 'auto',
+    stylesHover: false,
+    stylesClick: false
+  };
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var viz = new $jit.Viz({
+    NodeStyles: {
+      enable: true,
+      type: 'Native',
+      stylesHover: {
+        dim: 30,
+        color: '#fcc'
+      },
+      duration: 600
+    }
+  });
+  (end code)
+
+  Parameters:
+  
+  enable - (boolean) Default's *false*. Whether to enable this option.
+  type - (string) Default's *auto*. Use this to attach the hover/click events in the nodes or the nodes labels (if they have been defined as DOM elements: 'HTML' or 'SVG', see <Options.Label> for more details). The default 'auto' value will set NodeStyles to the same type defined for <Options.Label>.
+  stylesHover - (boolean|object) Default's *false*. An object with node styles just like the ones defined for <Options.Node> or *false* otherwise.
+  stylesClick - (boolean|object) Default's *false*. An object with node styles just like the ones defined for <Options.Node> or *false* otherwise.
+*/
+
+Options.NodeStyles = {
+  $extend: false,
+  
+  enable: false,
+  type: 'auto',
+  stylesHover: false,
+  stylesClick: false
+};
+
+
+/*
+ * File: Options.Events.js
+ *
+*/
+
+/*
+  Object: Options.Events
+  
+  Configuration for adding mouse/touch event handlers to Nodes.
+  
+  Syntax:
+  
+  (start code js)
+  Options.Events = {
+    enable: false,
+    enableForEdges: false,
+    type: 'auto',
+    onClick: $.empty,
+    onRightClick: $.empty,
+    onMouseMove: $.empty,
+    onMouseEnter: $.empty,
+    onMouseLeave: $.empty,
+    onDragStart: $.empty,
+    onDragMove: $.empty,
+    onDragCancel: $.empty,
+    onDragEnd: $.empty,
+    onTouchStart: $.empty,
+    onTouchMove: $.empty,
+    onTouchEnd: $.empty,
+    onTouchCancel: $.empty,
+    onMouseWheel: $.empty
+  };
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var viz = new $jit.Viz({
+    Events: {
+      enable: true,
+      onClick: function(node, eventInfo, e) {
+        viz.doSomething();
+      },
+      onMouseEnter: function(node, eventInfo, e) {
+        viz.canvas.getElement().style.cursor = 'pointer';
+      },
+      onMouseLeave: function(node, eventInfo, e) {
+        viz.canvas.getElement().style.cursor = '';
+      }
+    }
+  });
+  (end code)
+  
+  Parameters:
+  
+  enable - (boolean) Default's *false*. Whether to enable the Event system.
+  enableForEdges - (boolean) Default's *false*. Whether to track events also in arcs. If *true* the same callbacks -described below- are used for nodes *and* edges. A simple duck type check for edges is to check for *node.nodeFrom*.
+  type - (string) Default's 'auto'. Whether to attach the events onto the HTML labels (via event delegation) or to use the custom 'Native' canvas Event System of the library. 'auto' is set when you let the <Options.Label> *type* parameter decide this.
+  onClick(node, eventInfo, e) - Triggered when a user performs a click in the canvas. *node* is the <Graph.Node> clicked or false if no node has been clicked. *e* is the grabbed event (should return the native event in a cross-browser manner). *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas. 
+  onRightClick(node, eventInfo, e) - Triggered when a user performs a right click in the canvas. *node* is the <Graph.Node> right clicked or false if no node has been clicked. *e* is the grabbed event (should return the native event in a cross-browser manner). *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas. 
+  onMouseMove(node, eventInfo, e) - Triggered when the user moves the mouse. *node* is the <Graph.Node> under the cursor as it's moving over the canvas or false if no node has been clicked. *e* is the grabbed event (should return the native event in a cross-browser manner).  *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas.
+  onMouseEnter(node, eventInfo, e) - Triggered when a user moves the mouse over a node. *node* is the <Graph.Node> that the mouse just entered. *e* is the grabbed event (should return the native event in a cross-browser manner). *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas. 
+  onMouseLeave(node, eventInfo, e) - Triggered when the user mouse-outs a node. *node* is the <Graph.Node> 'mouse-outed'. *e* is the grabbed event (should return the native event in a cross-browser manner). *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas. 
+  onDragStart(node, eventInfo, e) - Triggered when the user mouse-downs over a node. *node* is the <Graph.Node> being pressed. *e* is the grabbed event (should return the native event in a cross-browser manner). *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas. 
+  onDragMove(node, eventInfo, e) - Triggered when a user, after pressing the mouse button over a node, moves the mouse around. *node* is the <Graph.Node> being dragged. *e* is the grabbed event (should return the native event in a cross-browser manner). *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas. 
+  onDragEnd(node, eventInfo, e) - Triggered when a user finished dragging a node. *node* is the <Graph.Node> being dragged. *e* is the grabbed event (should return the native event in a cross-browser manner). *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas. 
+  onDragCancel(node, eventInfo, e) - Triggered when the user releases the mouse button over a <Graph.Node> that wasn't dragged (i.e. the user didn't perform any mouse movement after pressing the mouse button). *node* is the <Graph.Node> being dragged. *e* is the grabbed event (should return the native event in a cross-browser manner). *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas. 
+  onTouchStart(node, eventInfo, e) - Behaves just like onDragStart. 
+  onTouchMove(node, eventInfo, e) - Behaves just like onDragMove. 
+  onTouchEnd(node, eventInfo, e) - Behaves just like onDragEnd. 
+  onTouchCancel(node, eventInfo, e) - Behaves just like onDragCancel.
+  onMouseWheel(delta, e) - Triggered when the user uses the mouse scroll over the canvas. *delta* is 1 or -1 depending on the sense of the mouse scroll.
+*/
+
+Options.Events = {
+  $extend: false,
+  
+  enable: false,
+  enableForEdges: false,
+  type: 'auto',
+  onClick: $.empty,
+  onRightClick: $.empty,
+  onMouseMove: $.empty,
+  onMouseEnter: $.empty,
+  onMouseLeave: $.empty,
+  onDragStart: $.empty,
+  onDragMove: $.empty,
+  onDragCancel: $.empty,
+  onDragEnd: $.empty,
+  onTouchStart: $.empty,
+  onTouchMove: $.empty,
+  onTouchEnd: $.empty,
+  onMouseWheel: $.empty
+};
+
+/*
+ * File: Options.Navigation.js
+ *
+*/
+
+/*
+  Object: Options.Navigation
+  
+  Panning and zooming options for Graph/Tree based visualizations. These options are implemented 
+  by all visualizations except charts (<AreaChart>, <BarChart> and <PieChart>).
+  
+  Syntax:
+  
+  (start code js)
+
+  Options.Navigation = {
+    enable: false,
+    type: 'auto',
+    panning: false, //true, 'avoid nodes'
+    zooming: false
+  };
+  
+  (end code)
+  
+  Example:
+    
+  (start code js)
+  var viz = new $jit.Viz({
+    Navigation: {
+      enable: true,
+      panning: 'avoid nodes',
+      zooming: 20
+    }
+  });
+  (end code)
+  
+  Parameters:
+  
+  enable - (boolean) Default's *false*. Whether to enable Navigation capabilities.
+  type - (string) Default's 'auto'. Whether to attach the navigation events onto the HTML labels (via event delegation) or to use the custom 'Native' canvas Event System of the library. When 'auto' set when you let the <Options.Label> *type* parameter decide this.
+  panning - (boolean|string) Default's *false*. Set this property to *true* if you want to add Drag and Drop panning support to the visualization. You can also set this parameter to 'avoid nodes' to enable DnD panning but disable it if the DnD is taking place over a node. This is useful when some other events like Drag & Drop for nodes are added to <Graph.Nodes>.
+  zooming - (boolean|number) Default's *false*. Set this property to a numeric value to turn mouse-scroll zooming on. The number will be proportional to the mouse-scroll sensitivity.
+  
+*/
+
+Options.Navigation = {
+  $extend: false,
+  
+  enable: false,
+  type: 'auto',
+  panning: false, //true | 'avoid nodes'
+  zooming: false
+};
+
+/*
+ * File: Options.Controller.js
+ *
+*/
+
+/*
+  Object: Options.Controller
+  
+  Provides controller methods. Controller methods are callback functions that get called at different stages 
+  of the animation, computing or plotting of the visualization.
+  
+  Implemented by:
+    
+  All visualizations except charts (<AreaChart>, <BarChart> and <PieChart>).
+  
+  Syntax:
+  
+  (start code js)
+
+  Options.Controller = {
+    onBeforeCompute: $.empty,
+    onAfterCompute:  $.empty,
+    onCreateLabel:   $.empty,
+    onPlaceLabel:    $.empty,
+    onComplete:      $.empty,
+    onBeforePlotLine:$.empty,
+    onAfterPlotLine: $.empty,
+    onBeforePlotNode:$.empty,
+    onAfterPlotNode: $.empty,
+    request:         false
+  };
+  
+  (end code)
+  
+  Example:
+    
+  (start code js)
+  var viz = new $jit.Viz({
+    onBeforePlotNode: function(node) {
+      if(node.selected) {
+        node.setData('color', '#ffc');
+      } else {
+        node.removeData('color');
+      }
+    },
+    onBeforePlotLine: function(adj) {
+      if(adj.nodeFrom.selected && adj.nodeTo.selected) {
+        adj.setData('color', '#ffc');
+      } else {
+        adj.removeData('color');
+      }
+    },
+    onAfterCompute: function() {
+      alert("computed!");
+    }
+  });
+  (end code)
+  
+  Parameters:
+
+   onBeforeCompute(node) - This method is called right before performing all computations and animations. The selected <Graph.Node> is passed as parameter.
+   onAfterCompute() - This method is triggered after all animations or computations ended.
+   onCreateLabel(domElement, node) - This method receives a new label DIV element as first parameter, and the corresponding <Graph.Node> as second parameter. This method will only be called once for each label. This method is useful when adding events or styles to the labels used by the JIT.
+   onPlaceLabel(domElement, node) - This method receives a label DIV element as first parameter and the corresponding <Graph.Node> as second parameter. This method is called each time a label has been placed in the visualization, for example at each step of an animation, and thus it allows you to update the labels properties, such as size or position. Note that onPlaceLabel will be triggered after updating the labels positions. That means that, for example, the left and top css properties are already updated to match the nodes positions. Width and height properties are not set however.
+   onBeforePlotNode(node) - This method is triggered right before plotting each <Graph.Node>. This method is useful for changing a node style right before plotting it.
+   onAfterPlotNode(node) - This method is triggered right after plotting each <Graph.Node>.
+   onBeforePlotLine(adj) - This method is triggered right before plotting a <Graph.Adjacence>. This method is useful for adding some styles to a particular edge before being plotted.
+   onAfterPlotLine(adj) - This method is triggered right after plotting a <Graph.Adjacence>.
+
+    *Used in <ST>, <TM.Base> and <Icicle> visualizations*
+    
+    request(nodeId, level, onComplete) - This method is used for buffering information into the visualization. When clicking on an empty node, the visualization will make a request for this node's subtrees, specifying a given level for this subtree (defined by _levelsToShow_). Once the request is completed, the onComplete callback should be called with the given result. This is useful to provide on-demand information into the visualizations withought having to load the entire information from start. The parameters used by this method are _nodeId_, which is the id of the root of the subtree to request, _level_ which is the depth of the subtree to be requested (0 would mean just the root node). _onComplete_ is an object having the callback method _onComplete.onComplete(json)_ that should be called once the json has been retrieved.  
+ 
+ */
+Options.Controller = {
+  $extend: true,
+  
+  onBeforeCompute: $.empty,
+  onAfterCompute:  $.empty,
+  onCreateLabel:   $.empty,
+  onPlaceLabel:    $.empty,
+  onComplete:      $.empty,
+  onBeforePlotLine:$.empty,
+  onAfterPlotLine: $.empty,
+  onBeforePlotNode:$.empty,
+  onAfterPlotNode: $.empty,
+  request:         false
+};
+
+
+/*
+ * File: Extras.js
+ * 
+ * Provides Extras such as Tips and Style Effects.
+ * 
+ * Description:
+ * 
+ * Provides the <Tips> and <NodeStyles> classes and functions.
+ *
+ */
+
+/*
+ * Manager for mouse events (clicking and mouse moving).
+ * 
+ * This class is used for registering objects implementing onClick
+ * and onMousemove methods. These methods are called when clicking or
+ * moving the mouse around  the Canvas.
+ * For now, <Tips> and <NodeStyles> are classes implementing these methods.
+ * 
+ */
+var ExtrasInitializer = {
+  initialize: function(className, viz) {
+    this.viz = viz;
+    this.canvas = viz.canvas;
+    this.config = viz.config[className];
+    this.nodeTypes = viz.fx.nodeTypes;
+    var type = this.config.type;
+    this.dom = type == 'auto'? (viz.config.Label.type != 'Native') : (type != 'Native');
+    this.labelContainer = this.dom && viz.labels.getLabelContainer();
+    this.isEnabled() && this.initializePost();
+  },
+  initializePost: $.empty,
+  setAsProperty: $.lambda(false),
+  isEnabled: function() {
+    return this.config.enable;
+  },
+  isLabel: function(e, win, group) {
+    e = $.event.get(e, win);
+    var labelContainer = this.labelContainer,
+        target = e.target || e.srcElement,
+        related = e.relatedTarget;
+    if(group) {
+      return related && related == this.viz.canvas.getCtx().canvas 
+          && !!target && this.isDescendantOf(target, labelContainer);
+    } else {
+      return this.isDescendantOf(target, labelContainer);
+    }
+  },
+  isDescendantOf: function(elem, par) {
+    while(elem && elem.parentNode) {
+      if(elem.parentNode == par)
+        return elem;
+      elem = elem.parentNode;
+    }
+    return false;
+  }
+};
+
+var EventsInterface = {
+  onMouseUp: $.empty,
+  onMouseDown: $.empty,
+  onMouseMove: $.empty,
+  onMouseOver: $.empty,
+  onMouseOut: $.empty,
+  onMouseWheel: $.empty,
+  onTouchStart: $.empty,
+  onTouchMove: $.empty,
+  onTouchEnd: $.empty,
+  onTouchCancel: $.empty
+};
+
+var MouseEventsManager = new Class({
+  initialize: function(viz) {
+    this.viz = viz;
+    this.canvas = viz.canvas;
+    this.node = false;
+    this.edge = false;
+    this.registeredObjects = [];
+    this.attachEvents();
+  },
+  
+  attachEvents: function() {
+    var htmlCanvas = this.canvas.getElement(), 
+        that = this;
+    htmlCanvas.oncontextmenu = $.lambda(false);
+    $.addEvents(htmlCanvas, {
+      'mouseup': function(e, win) {
+        var event = $.event.get(e, win);
+        that.handleEvent('MouseUp', e, win, 
+            that.makeEventObject(e, win), 
+            $.event.isRightClick(event));
+      },
+      'mousedown': function(e, win) {
+        var event = $.event.get(e, win);
+        that.handleEvent('MouseDown', e, win, that.makeEventObject(e, win), 
+            $.event.isRightClick(event));
+      },
+      'mousemove': function(e, win) {
+        that.handleEvent('MouseMove', e, win, that.makeEventObject(e, win));
+      },
+      'mouseover': function(e, win) {
+        that.handleEvent('MouseOver', e, win, that.makeEventObject(e, win));
+      },
+      'mouseout': function(e, win) {
+        that.handleEvent('MouseOut', e, win, that.makeEventObject(e, win));
+      },
+      'touchstart': function(e, win) {
+        that.handleEvent('TouchStart', e, win, that.makeEventObject(e, win));
+      },
+      'touchmove': function(e, win) {
+        that.handleEvent('TouchMove', e, win, that.makeEventObject(e, win));
+      },
+      'touchend': function(e, win) {
+        that.handleEvent('TouchEnd', e, win, that.makeEventObject(e, win));
+      }
+    });
+    //attach mousewheel event
+    var handleMouseWheel = function(e, win) {
+      var event = $.event.get(e, win);
+      var wheel = $.event.getWheel(event);
+      that.handleEvent('MouseWheel', e, win, wheel);
+    };
+    //TODO(nico): this is a horrible check for non-gecko browsers!
+    if(!document.getBoxObjectFor && window.mozInnerScreenX == null) {
+      $.addEvent(htmlCanvas, 'mousewheel', handleMouseWheel);
+    } else {
+      htmlCanvas.addEventListener('DOMMouseScroll', handleMouseWheel, false);
+    }
+  },
+  
+  register: function(obj) {
+    this.registeredObjects.push(obj);
+  },
+  
+  handleEvent: function() {
+    var args = Array.prototype.slice.call(arguments),
+        type = args.shift();
+    for(var i=0, regs=this.registeredObjects, l=regs.length; i<l; i++) {
+      regs[i]['on' + type].apply(regs[i], args);
+    }
+  },
+  
+  makeEventObject: function(e, win) {
+    var that = this,
+        graph = this.viz.graph,
+        fx = this.viz.fx,
+        ntypes = fx.nodeTypes,
+        etypes = fx.edgeTypes;
+    return {
+      pos: false,
+      node: false,
+      edge: false,
+      contains: false,
+      getNodeCalled: false,
+      getEdgeCalled: false,
+      getPos: function() {
+        //TODO(nico): check why this can't be cache anymore when using edge detection
+        //if(this.pos) return this.pos;
+        var canvas = that.viz.canvas,
+            s = canvas.getSize(),
+            p = canvas.getPos(),
+            ox = canvas.translateOffsetX,
+            oy = canvas.translateOffsetY,
+            sx = canvas.scaleOffsetX,
+            sy = canvas.scaleOffsetY,
+            pos = $.event.getPos(e, win);
+        this.pos = {
+          x: (pos.x - p.x - s.width/2 - ox) * 1/sx,
+          y: (pos.y - p.y - s.height/2 - oy) * 1/sy
+        };
+        return this.pos;
+      },
+      getNode: function() {
+        if(this.getNodeCalled) return this.node;
+        this.getNodeCalled = true;
+        for(var id in graph.nodes) {
+          var n = graph.nodes[id],
+              geom = n && ntypes[n.getData('type')],
+              contains = geom && geom.contains && geom.contains.call(fx, n, this.getPos());
+          if(contains) {
+            this.contains = contains;
+            return that.node = this.node = n;
+          }
+        }
+        return that.node = this.node = false;
+      },
+      getEdge: function() {
+        if(this.getEdgeCalled) return this.edge;
+        this.getEdgeCalled = true;
+        var hashset = {};
+        for(var id in graph.edges) {
+          var edgeFrom = graph.edges[id];
+          hashset[id] = true;
+          for(var edgeId in edgeFrom) {
+            if(edgeId in hashset) continue;
+            var e = edgeFrom[edgeId],
+                geom = e && etypes[e.getData('type')],
+                contains = geom && geom.contains && geom.contains.call(fx, e, this.getPos());
+            if(contains) {
+              this.contains = contains;
+              return that.edge = this.edge = e;
+            }
+          }
+        }
+        return that.edge = this.edge = false;
+      },
+      getContains: function() {
+        if(this.getNodeCalled) return this.contains;
+        this.getNode();
+        return this.contains;
+      }
+    };
+  }
+});
+
+/* 
+ * Provides the initialization function for <NodeStyles> and <Tips> implemented 
+ * by all main visualizations.
+ *
+ */
+var Extras = {
+  initializeExtras: function() {
+    var mem = new MouseEventsManager(this), that = this;
+    $.each(['NodeStyles', 'Tips', 'Navigation', 'Events'], function(k) {
+      var obj = new Extras.Classes[k](k, that);
+      if(obj.isEnabled()) {
+        mem.register(obj);
+      }
+      if(obj.setAsProperty()) {
+        that[k.toLowerCase()] = obj;
+      }
+    });
+  }   
+};
+
+Extras.Classes = {};
+/*
+  Class: Events
+   
+  This class defines an Event API to be accessed by the user.
+  The methods implemented are the ones defined in the <Options.Events> object.
+*/
+
+Extras.Classes.Events = new Class({
+  Implements: [ExtrasInitializer, EventsInterface],
+  
+  initializePost: function() {
+    this.fx = this.viz.fx;
+    this.ntypes = this.viz.fx.nodeTypes;
+    this.etypes = this.viz.fx.edgeTypes;
+    
+    this.hovered = false;
+    this.pressed = false;
+    this.touched = false;
+
+    this.touchMoved = false;
+    this.moved = false;
+    
+  },
+  
+  setAsProperty: $.lambda(true),
+  
+  onMouseUp: function(e, win, event, isRightClick) {
+    var evt = $.event.get(e, win);
+    if(!this.moved) {
+      if(isRightClick) {
+        this.config.onRightClick(this.hovered, event, evt);
+      } else {
+        this.config.onClick(this.pressed, event, evt);
+      }
+    }
+    if(this.pressed) {
+      if(this.moved) {
+        this.config.onDragEnd(this.pressed, event, evt);
+      } else {
+        this.config.onDragCancel(this.pressed, event, evt);
+      }
+      this.pressed = this.moved = false;
+    }
+  },
+
+  onMouseOut: function(e, win, event) {
+   //mouseout a label
+   var evt = $.event.get(e, win), label;
+   if(this.dom && (label = this.isLabel(e, win, true))) {
+     this.config.onMouseLeave(this.viz.graph.getNode(label.id),
+                              event, evt);
+     this.hovered = false;
+     return;
+   }
+   //mouseout canvas
+   var rt = evt.relatedTarget,
+       canvasWidget = this.canvas.getElement();
+   while(rt && rt.parentNode) {
+     if(canvasWidget == rt.parentNode) return;
+     rt = rt.parentNode;
+   }
+   if(this.hovered) {
+     this.config.onMouseLeave(this.hovered,
+         event, evt);
+     this.hovered = false;
+   }
+  },
+  
+  onMouseOver: function(e, win, event) {
+    //mouseover a label
+    var evt = $.event.get(e, win), label;
+    if(this.dom && (label = this.isLabel(e, win, true))) {
+      this.hovered = this.viz.graph.getNode(label.id);
+      this.config.onMouseEnter(this.hovered,
+                               event, evt);
+    }
+  },
+  
+  onMouseMove: function(e, win, event) {
+   var label, evt = $.event.get(e, win);
+   if(this.pressed) {
+     this.moved = true;
+     this.config.onDragMove(this.pressed, event, evt);
+     return;
+   }
+   if(this.dom) {
+     this.config.onMouseMove(this.hovered,
+         event, evt);
+   } else {
+     if(this.hovered) {
+       var hn = this.hovered;
+       var geom = hn.nodeFrom? this.etypes[hn.getData('type')] : this.ntypes[hn.getData('type')];
+       var contains = geom && geom.contains 
+         && geom.contains.call(this.fx, hn, event.getPos());
+       if(contains) {
+         this.config.onMouseMove(hn, event, evt);
+         return;
+       } else {
+         this.config.onMouseLeave(hn, event, evt);
+         this.hovered = false;
+       }
+     }
+     if(this.hovered = (event.getNode() || (this.config.enableForEdges && event.getEdge()))) {
+       this.config.onMouseEnter(this.hovered, event, evt);
+     } else {
+       this.config.onMouseMove(false, event, evt);
+     }
+   }
+  },
+  
+  onMouseWheel: function(e, win, delta) {
+    this.config.onMouseWheel(delta, $.event.get(e, win));
+  },
+  
+  onMouseDown: function(e, win, event) {
+    var evt = $.event.get(e, win), label;
+    if(this.dom) {
+      if(label = this.isLabel(e, win)) {
+        this.pressed = this.viz.graph.getNode(label.id);
+      }
+    } else {
+      this.pressed = event.getNode() || (this.config.enableForEdges && event.getEdge());
+    }
+    this.pressed && this.config.onDragStart(this.pressed, event, evt);
+  },
+  
+  onTouchStart: function(e, win, event) {
+    var evt = $.event.get(e, win), label;
+    if(this.dom && (label = this.isLabel(e, win))) {
+      this.touched = this.viz.graph.getNode(label.id);
+    } else {
+      this.touched = event.getNode() || (this.config.enableForEdges && event.getEdge());
+    }
+    this.touched && this.config.onTouchStart(this.touched, event, evt);
+  },
+  
+  onTouchMove: function(e, win, event) {
+    var evt = $.event.get(e, win);
+    if(this.touched) {
+      this.touchMoved = true;
+      this.config.onTouchMove(this.touched, event, evt);
+    }
+  },
+  
+  onTouchEnd: function(e, win, event) {
+    var evt = $.event.get(e, win);
+    if(this.touched) {
+      if(this.touchMoved) {
+        this.config.onTouchEnd(this.touched, event, evt);
+      } else {
+        this.config.onTouchCancel(this.touched, event, evt);
+      }
+      this.touched = this.touchMoved = false;
+    }
+  }
+});
+
+/*
+   Class: Tips
+    
+   A class containing tip related functions. This class is used internally.
+   
+   Used by:
+   
+   <ST>, <Sunburst>, <Hypertree>, <RGraph>, <TM>, <ForceDirected>, <Icicle>
+   
+   See also:
+   
+   <Options.Tips>
+*/
+
+Extras.Classes.Tips = new Class({
+  Implements: [ExtrasInitializer, EventsInterface],
+  
+  initializePost: function() {
+    //add DOM tooltip
+    if(document.body) {
+      var tip = $('_tooltip') || document.createElement('div');
+      tip.id = '_tooltip';
+      tip.className = 'tip';
+      $.extend(tip.style, {
+        position: 'absolute',
+        display: 'none',
+        zIndex: 13000
+      });
+      document.body.appendChild(tip);
+      this.tip = tip;
+      this.node = false;
+    }
+  },
+  
+  setAsProperty: $.lambda(true),
+  
+  onMouseOut: function(e, win) {
+    //mouseout a label
+    var evt = $.event.get(e, win);
+    if(this.dom && this.isLabel(e, win, true)) {
+      this.hide(true);
+      return;
+    }
+    //mouseout canvas
+    var rt = e.relatedTarget,
+        canvasWidget = this.canvas.getElement();
+    while(rt && rt.parentNode) {
+      if(canvasWidget == rt.parentNode) return;
+      rt = rt.parentNode;
+    }
+    this.hide(false);
+  },
+  
+  onMouseOver: function(e, win) {
+    //mouseover a label
+    var label;
+    if(this.dom && (label = this.isLabel(e, win, false))) {
+      this.node = this.viz.graph.getNode(label.id);
+      this.config.onShow(this.tip, this.node, label);
+    }
+  },
+  
+  onMouseMove: function(e, win, opt) {
+    if(this.dom && this.isLabel(e, win)) {
+      this.setTooltipPosition($.event.getPos(e, win));
+    }
+    if(!this.dom) {
+      var node = opt.getNode();
+      if(!node) {
+        this.hide(true);
+        return;
+      }
+      if(this.config.force || !this.node || this.node.id != node.id) {
+        this.node = node;
+        this.config.onShow(this.tip, node, opt.getContains());
+      }
+      this.setTooltipPosition($.event.getPos(e, win));
+    }
+  },
+  
+  setTooltipPosition: function(pos) {
+    var tip = this.tip, 
+        style = tip.style, 
+        cont = this.config;
+    style.display = '';
+    //get window dimensions
+    var win = {
+      'height': document.body.clientHeight,
+      'width': document.body.clientWidth
+    };
+    //get tooltip dimensions
+    var obj = {
+      'width': tip.offsetWidth,
+      'height': tip.offsetHeight  
+    };
+    //set tooltip position
+    var x = cont.offsetX, y = cont.offsetY;
+    style.top = ((pos.y + y + obj.height > win.height)?  
+        (pos.y - obj.height - y) : pos.y + y) + 'px';
+    style.left = ((pos.x + obj.width + x > win.width)? 
+        (pos.x - obj.width - x) : pos.x + x) + 'px';
+  },
+  
+  hide: function(triggerCallback) {
+    this.tip.style.display = 'none';
+    triggerCallback && this.config.onHide();
+  }
+});
+
+/*
+  Class: NodeStyles
+   
+  Change node styles when clicking or hovering a node. This class is used internally.
+  
+  Used by:
+  
+  <ST>, <Sunburst>, <Hypertree>, <RGraph>, <TM>, <ForceDirected>, <Icicle>
+  
+  See also:
+  
+  <Options.NodeStyles>
+*/
+Extras.Classes.NodeStyles = new Class({
+  Implements: [ExtrasInitializer, EventsInterface],
+  
+  initializePost: function() {
+    this.fx = this.viz.fx;
+    this.types = this.viz.fx.nodeTypes;
+    this.nStyles = this.config;
+    this.nodeStylesOnHover = this.nStyles.stylesHover;
+    this.nodeStylesOnClick = this.nStyles.stylesClick;
+    this.hoveredNode = false;
+    this.fx.nodeFxAnimation = new Animation();
+    
+    this.down = false;
+    this.move = false;
+  },
+  
+  onMouseOut: function(e, win) {
+    this.down = this.move = false;
+    if(!this.hoveredNode) return;
+    //mouseout a label
+    if(this.dom && this.isLabel(e, win, true)) {
+      this.toggleStylesOnHover(this.hoveredNode, false);
+    }
+    //mouseout canvas
+    var rt = e.relatedTarget,
+        canvasWidget = this.canvas.getElement();
+    while(rt && rt.parentNode) {
+      if(canvasWidget == rt.parentNode) return;
+      rt = rt.parentNode;
+    }
+    this.toggleStylesOnHover(this.hoveredNode, false);
+    this.hoveredNode = false;
+  },
+  
+  onMouseOver: function(e, win) {
+    //mouseover a label
+    var label;
+    if(this.dom && (label = this.isLabel(e, win, true))) {
+      var node = this.viz.graph.getNode(label.id);
+      if(node.selected) return;
+      this.hoveredNode = node;
+      this.toggleStylesOnHover(this.hoveredNode, true);
+    }
+  },
+  
+  onMouseDown: function(e, win, event, isRightClick) {
+    if(isRightClick) return;
+    var label;
+    if(this.dom && (label = this.isLabel(e, win))) {
+      this.down = this.viz.graph.getNode(label.id);
+    } else if(!this.dom) {
+      this.down = event.getNode();
+    }
+    this.move = false;
+  },
+  
+  onMouseUp: function(e, win, event, isRightClick) {
+    if(isRightClick) return;
+    if(!this.move) {
+      this.onClick(event.getNode());
+    }
+    this.down = this.move = false;
+  },
+  
+  getRestoredStyles: function(node, type) {
+    var restoredStyles = {}, 
+        nStyles = this['nodeStylesOn' + type];
+    for(var prop in nStyles) {
+      restoredStyles[prop] = node.styles['$' + prop];
+    }
+    return restoredStyles;
+  },
+  
+  toggleStylesOnHover: function(node, set) {
+    if(this.nodeStylesOnHover) {
+      this.toggleStylesOn('Hover', node, set);
+    }
+  },
+
+  toggleStylesOnClick: function(node, set) {
+    if(this.nodeStylesOnClick) {
+      this.toggleStylesOn('Click', node, set);
+    }
+  },
+  
+  toggleStylesOn: function(type, node, set) {
+    var viz = this.viz;
+    var nStyles = this.nStyles;
+    if(set) {
+      var that = this;
+      if(!node.styles) {
+        node.styles = $.merge(node.data, {});
+      }
+      for(var s in this['nodeStylesOn' + type]) {
+        var $s = '$' + s;
+        if(!($s in node.styles)) {
+            node.styles[$s] = node.getData(s); 
+        }
+      }
+      viz.fx.nodeFx($.extend({
+        'elements': {
+          'id': node.id,
+          'properties': that['nodeStylesOn' + type]
+         },
+         transition: Trans.Quart.easeOut,
+         duration:300,
+         fps:40
+      }, this.config));
+    } else {
+      var restoredStyles = this.getRestoredStyles(node, type);
+      viz.fx.nodeFx($.extend({
+        'elements': {
+          'id': node.id,
+          'properties': restoredStyles
+         },
+         transition: Trans.Quart.easeOut,
+         duration:300,
+         fps:40
+      }, this.config));
+    }
+  },
+
+  onClick: function(node) {
+    if(!node) return;
+    var nStyles = this.nodeStylesOnClick;
+    if(!nStyles) return;
+    //if the node is selected then unselect it
+    if(node.selected) {
+      this.toggleStylesOnClick(node, false);
+      delete node.selected;
+    } else {
+      //unselect all selected nodes...
+      this.viz.graph.eachNode(function(n) {
+        if(n.selected) {
+          for(var s in nStyles) {
+            n.setData(s, n.styles['$' + s], 'end');
+          }
+          delete n.selected;
+        }
+      });
+      //select clicked node
+      this.toggleStylesOnClick(node, true);
+      node.selected = true;
+      delete node.hovered;
+      this.hoveredNode = false;
+    }
+  },
+  
+  onMouseMove: function(e, win, event) {
+    //if mouse button is down and moving set move=true
+    if(this.down) this.move = true;
+    //already handled by mouseover/out
+    if(this.dom && this.isLabel(e, win)) return;
+    var nStyles = this.nodeStylesOnHover;
+    if(!nStyles) return;
+    
+    if(!this.dom) {
+      if(this.hoveredNode) {
+        var geom = this.types[this.hoveredNode.getData('type')];
+        var contains = geom && geom.contains && geom.contains.call(this.fx, 
+            this.hoveredNode, event.getPos());
+        if(contains) return;
+      }
+      var node = event.getNode();
+      //if no node is being hovered then just exit
+      if(!this.hoveredNode && !node) return;
+      //if the node is hovered then exit
+      if(node.hovered) return;
+      //select hovered node
+      if(node && !node.selected) {
+        //check if an animation is running and exit it
+        this.fx.nodeFxAnimation.stopTimer();
+        //unselect all hovered nodes...
+        this.viz.graph.eachNode(function(n) {
+          if(n.hovered && !n.selected) {
+            for(var s in nStyles) {
+              n.setData(s, n.styles['$' + s], 'end');
+            }
+            delete n.hovered;
+          }
+        });
+        //select hovered node
+        node.hovered = true;
+        this.hoveredNode = node;
+        this.toggleStylesOnHover(node, true);
+      } else if(this.hoveredNode && !this.hoveredNode.selected) {
+        //check if an animation is running and exit it
+        this.fx.nodeFxAnimation.stopTimer();
+        //unselect hovered node
+        this.toggleStylesOnHover(this.hoveredNode, false);
+        delete this.hoveredNode.hovered;
+        this.hoveredNode = false;
+      }
+    }
+  }
+});
+
+Extras.Classes.Navigation = new Class({
+  Implements: [ExtrasInitializer, EventsInterface],
+  
+  initializePost: function() {
+    this.pos = false;
+    this.pressed = false;
+  },
+  
+  onMouseWheel: function(e, win, scroll) {
+    if(!this.config.zooming) return;
+    $.event.stop($.event.get(e, win));
+    var val = this.config.zooming / 1000,
+        ans = 1 + scroll * val;
+    this.canvas.scale(ans, ans);
+  },
+  
+  onMouseDown: function(e, win, eventInfo) {
+    if(!this.config.panning) return;
+    if(this.config.panning == 'avoid nodes' && (this.dom? this.isLabel(e, win) : eventInfo.getNode())) return;
+    this.pressed = true;
+    this.pos = eventInfo.getPos();
+    var canvas = this.canvas,
+        ox = canvas.translateOffsetX,
+        oy = canvas.translateOffsetY,
+        sx = canvas.scaleOffsetX,
+        sy = canvas.scaleOffsetY;
+    this.pos.x *= sx;
+    this.pos.x += ox;
+    this.pos.y *= sy;
+    this.pos.y += oy;
+  },
+  
+  onMouseMove: function(e, win, eventInfo) {
+    if(!this.config.panning) return;
+    if(!this.pressed) return;
+    if(this.config.panning == 'avoid nodes' && (this.dom? this.isLabel(e, win) : eventInfo.getNode())) return;
+    var thispos = this.pos, 
+        currentPos = eventInfo.getPos(),
+        canvas = this.canvas,
+        ox = canvas.translateOffsetX,
+        oy = canvas.translateOffsetY,
+        sx = canvas.scaleOffsetX,
+        sy = canvas.scaleOffsetY;
+    currentPos.x *= sx;
+    currentPos.y *= sy;
+    currentPos.x += ox;
+    currentPos.y += oy;
+    var x = currentPos.x - thispos.x,
+        y = currentPos.y - thispos.y;
+    this.pos = currentPos;
+    this.canvas.translate(x * 1/sx, y * 1/sy);
+  },
+  
+  onMouseUp: function(e, win, eventInfo, isRightClick) {
+    if(!this.config.panning) return;
+    this.pressed = false;
+  }
+});
+
+
+/*
+ * File: Canvas.js
+ *
+ */
+
+/*
+ Class: Canvas
+ 
+ 	A canvas widget used by all visualizations. The canvas object can be accessed by doing *viz.canvas*. If you want to 
+ 	know more about <Canvas> options take a look at <Options.Canvas>.
+ 
+ A canvas widget is a set of DOM elements that wrap the native canvas DOM Element providing a consistent API and behavior 
+ across all browsers. It can also include Elements to add DOM (SVG or HTML) label support to all visualizations.
+ 
+ Example:
+ 
+ Suppose we have this HTML
+ 
+ (start code xml)
+ 	<div id="infovis"></div>
+ (end code)
+ 
+ Now we create a new Visualization
+ 
+ (start code js)
+ 	var viz = new $jit.Viz({
+ 		//Where to inject the canvas. Any div container will do.
+ 		'injectInto':'infovis',
+		 //width and height for canvas. 
+		 //Default's to the container offsetWidth and Height.
+		 'width': 900,
+		 'height':500
+	 });
+ (end code)
+
+ The generated HTML will look like this
+ 
+ (start code xml)
+ <div id="infovis">
+ 	<div id="infovis-canvaswidget" style="position:relative;">
+ 	<canvas id="infovis-canvas" width=900 height=500
+ 	style="position:absolute; top:0; left:0; width:900px; height:500px;" />
+ 	<div id="infovis-label"
+ 	style="overflow:visible; position:absolute; top:0; left:0; width:900px; height:0px">
+ 	</div>
+ 	</div>
+ </div>
+ (end code)
+ 
+ As you can see, the generated HTML consists of a canvas DOM Element of id *infovis-canvas* and a div label container
+ of id *infovis-label*, wrapped in a main div container of id *infovis-canvaswidget*.
+ */
+
+var Canvas;
+(function() {
+  //check for native canvas support
+  var canvasType = typeof HTMLCanvasElement,
+      supportsCanvas = (canvasType == 'object' || canvasType == 'function');
+  //create element function
+  function $E(tag, props) {
+    var elem = document.createElement(tag);
+    for(var p in props) {
+      if(typeof props[p] == "object") {
+        $.extend(elem[p], props[p]);
+      } else {
+        elem[p] = props[p];
+      }
+    }
+    if (tag == "canvas" && !supportsCanvas && G_vmlCanvasManager) {
+      elem = G_vmlCanvasManager.initElement(document.body.appendChild(elem));
+    }
+    return elem;
+  }
+  //canvas widget which we will call just Canvas
+  $jit.Canvas = Canvas = new Class({
+    canvases: [],
+    pos: false,
+    element: false,
+    labelContainer: false,
+    translateOffsetX: 0,
+    translateOffsetY: 0,
+    scaleOffsetX: 1,
+    scaleOffsetY: 1,
+    
+    initialize: function(viz, opt) {
+      this.viz = viz;
+      this.opt = this.config = opt;
+      var id = $.type(opt.injectInto) == 'string'? 
+          opt.injectInto:opt.injectInto.id,
+          type = opt.type,
+          idLabel = id + "-label", 
+          wrapper = $(id),
+          width = opt.width || wrapper.offsetWidth,
+          height = opt.height || wrapper.offsetHeight;
+      this.id = id;
+      //canvas options
+      var canvasOptions = {
+        injectInto: id,
+        width: width,
+        height: height
+      };
+      //create main wrapper
+      this.element = $E('div', {
+        'id': id + '-canvaswidget',
+        'style': {
+          'position': 'relative',
+          'width': width + 'px',
+          'height': height + 'px'
+        }
+      });
+      //create label container
+      this.labelContainer = this.createLabelContainer(opt.Label.type, 
+          idLabel, canvasOptions);
+      //create primary canvas
+      this.canvases.push(new Canvas.Base[type]({
+        config: $.extend({idSuffix: '-canvas'}, canvasOptions),
+        plot: function(base) {
+          viz.fx.plot();
+        },
+        resize: function() {
+          viz.refresh();
+        }
+      }));
+      //create secondary canvas
+      var back = opt.background;
+      if(back) {
+        var backCanvas = new Canvas.Background[back.type](viz, $.extend(back, canvasOptions));
+        this.canvases.push(new Canvas.Base[type](backCanvas));
+      }
+      //insert canvases
+      var len = this.canvases.length;
+      while(len--) {
+        this.element.appendChild(this.canvases[len].canvas);
+        if(len > 0) {
+          this.canvases[len].plot();
+        }
+      }
+      this.element.appendChild(this.labelContainer);
+      wrapper.appendChild(this.element);
+      //Update canvas position when the page is scrolled.
+      var timer = null, that = this;
+      $.addEvent(window, 'scroll', function() {
+        clearTimeout(timer);
+        timer = setTimeout(function() {
+          that.getPos(true); //update canvas position
+        }, 500);
+      });
+    },
+    /*
+      Method: getCtx
+      
+      Returns the main canvas context object
+      
+      Example:
+      
+      (start code js)
+       var ctx = canvas.getCtx();
+       //Now I can use the native canvas context
+       //and for example change some canvas styles
+       ctx.globalAlpha = 1;
+      (end code)
+    */
+    getCtx: function(i) {
+      return this.canvases[i || 0].getCtx();
+    },
+    /*
+      Method: getConfig
+      
+      Returns the current Configuration for this Canvas Widget.
+      
+      Example:
+      
+      (start code js)
+       var config = canvas.getConfig();
+      (end code)
+    */
+    getConfig: function() {
+      return this.opt;
+    },
+    /*
+      Method: getElement
+
+      Returns the main Canvas DOM wrapper
+      
+      Example:
+      
+      (start code js)
+       var wrapper = canvas.getElement();
+       //Returns <div id="infovis-canvaswidget" ... >...</div> as element
+      (end code)
+    */
+    getElement: function() {
+      return this.element;
+    },
+    /*
+      Method: getSize
+      
+      Returns canvas dimensions.
+      
+      Returns:
+      
+      An object with *width* and *height* properties.
+      
+      Example:
+      (start code js)
+      canvas.getSize(); //returns { width: 900, height: 500 }
+      (end code)
+    */
+    getSize: function(i) {
+      return this.canvases[i || 0].getSize();
+    },
+    /*
+      Method: resize
+      
+      Resizes the canvas.
+      
+      Parameters:
+      
+      width - New canvas width.
+      height - New canvas height.
+      
+      Example:
+      
+      (start code js)
+       canvas.resize(width, height);
+      (end code)
+    
+    */
+    resize: function(width, height) {
+      this.getPos(true);
+      this.translateOffsetX = this.translateOffsetY = 0;
+      this.scaleOffsetX = this.scaleOffsetY = 1;
+      for(var i=0, l=this.canvases.length; i<l; i++) {
+        this.canvases[i].resize(width, height);
+      }
+      var style = this.element.style;
+      style.width = width + 'px';
+      style.height = height + 'px';
+      if(this.labelContainer)
+        this.labelContainer.style.width = width + 'px';
+    },
+    /*
+      Method: translate
+      
+      Applies a translation to the canvas.
+      
+      Parameters:
+      
+      x - (number) x offset.
+      y - (number) y offset.
+      disablePlot - (boolean) Default's *false*. Set this to *true* if you don't want to refresh the visualization.
+      
+      Example:
+      
+      (start code js)
+       canvas.translate(30, 30);
+      (end code)
+    
+    */
+    translate: function(x, y, disablePlot) {
+      this.translateOffsetX += x*this.scaleOffsetX;
+      this.translateOffsetY += y*this.scaleOffsetY;
+      for(var i=0, l=this.canvases.length; i<l; i++) {
+        this.canvases[i].translate(x, y, disablePlot);
+      }
+    },
+    /*
+      Method: scale
+      
+      Scales the canvas.
+      
+      Parameters:
+      
+      x - (number) scale value.
+      y - (number) scale value.
+      disablePlot - (boolean) Default's *false*. Set this to *true* if you don't want to refresh the visualization.
+      
+      Example:
+      
+      (start code js)
+       canvas.scale(0.5, 0.5);
+      (end code)
+    
+    */
+    scale: function(x, y, disablePlot) {
+      var px = this.scaleOffsetX * x,
+          py = this.scaleOffsetY * y;
+      var dx = this.translateOffsetX * (x -1) / px,
+          dy = this.translateOffsetY * (y -1) / py;
+      this.scaleOffsetX = px;
+      this.scaleOffsetY = py;
+      for(var i=0, l=this.canvases.length; i<l; i++) {
+        this.canvases[i].scale(x, y, true);
+      }
+      this.translate(dx, dy, false);
+    },
+    /*
+      Method: getPos
+      
+      Returns the canvas position as an *x, y* object.
+      
+      Parameters:
+      
+      force - (boolean) Default's *false*. Set this to *true* if you want to recalculate the position without using any cache information.
+      
+      Returns:
+      
+      An object with *x* and *y* properties.
+      
+      Example:
+      (start code js)
+      canvas.getPos(true); //returns { x: 900, y: 500 }
+      (end code)
+    */
+    getPos: function(force){
+      if(force || !this.pos) {
+        return this.pos = $.getPos(this.getElement());
+      }
+      return this.pos;
+    },
+    /*
+       Method: clear
+       
+       Clears the canvas.
+    */
+    clear: function(i){
+      this.canvases[i||0].clear();
+    },
+    
+    path: function(type, action){
+      var ctx = this.canvases[0].getCtx();
+      ctx.beginPath();
+      action(ctx);
+      ctx[type]();
+      ctx.closePath();
+    },
+    
+    createLabelContainer: function(type, idLabel, dim) {
+      var NS = 'http://www.w3.org/2000/svg';
+      if(type == 'HTML' || type == 'Native') {
+        return $E('div', {
+          'id': idLabel,
+          'style': {
+            'overflow': 'visible',
+            'position': 'absolute',
+            'top': 0,
+            'left': 0,
+            'width': dim.width + 'px',
+            'height': 0
+          }
+        });
+      } else if(type == 'SVG') {
+        var svgContainer = document.createElementNS(NS, 'svg:svg');
+        svgContainer.setAttribute("width", dim.width);
+        svgContainer.setAttribute('height', dim.height);
+        var style = svgContainer.style;
+        style.position = 'absolute';
+        style.left = style.top = '0px';
+        var labelContainer = document.createElementNS(NS, 'svg:g');
+        labelContainer.setAttribute('width', dim.width);
+        labelContainer.setAttribute('height', dim.height);
+        labelContainer.setAttribute('x', 0);
+        labelContainer.setAttribute('y', 0);
+        labelContainer.setAttribute('id', idLabel);
+        svgContainer.appendChild(labelContainer);
+        return svgContainer;
+      }
+    }
+  });
+  //base canvas wrapper
+  Canvas.Base = {};
+  Canvas.Base['2D'] = new Class({
+    translateOffsetX: 0,
+    translateOffsetY: 0,
+    scaleOffsetX: 1,
+    scaleOffsetY: 1,
+
+    initialize: function(viz) {
+      this.viz = viz;
+      this.opt = viz.config;
+      this.size = false;
+      this.createCanvas();
+      this.translateToCenter();
+    },
+    createCanvas: function() {
+      var opt = this.opt,
+          width = opt.width,
+          height = opt.height;
+      this.canvas = $E('canvas', {
+        'id': opt.injectInto + opt.idSuffix,
+        'width': width,
+        'height': height,
+        'style': {
+          'position': 'absolute',
+          'top': 0,
+          'left': 0,
+          'width': width + 'px',
+          'height': height + 'px'
+        }
+      });
+    },
+    getCtx: function() {
+      if(!this.ctx) 
+        return this.ctx = this.canvas.getContext('2d');
+      return this.ctx;
+    },
+    getSize: function() {
+      if(this.size) return this.size;
+      var canvas = this.canvas;
+      return this.size = {
+        width: canvas.width,
+        height: canvas.height
+      };
+    },
+    translateToCenter: function(ps) {
+      var size = this.getSize(),
+          width = ps? (size.width - ps.width - this.translateOffsetX*2) : size.width;
+          height = ps? (size.height - ps.height - this.translateOffsetY*2) : size.height;
+      var ctx = this.getCtx();
+      ps && ctx.scale(1/this.scaleOffsetX, 1/this.scaleOffsetY);
+      ctx.translate(width/2, height/2);
+    },
+    resize: function(width, height) {
+      var size = this.getSize(),
+          canvas = this.canvas,
+          styles = canvas.style;
+      this.size = false;
+      canvas.width = width;
+      canvas.height = height;
+      styles.width = width + "px";
+      styles.height = height + "px";
+      //small ExCanvas fix
+      if(!supportsCanvas) {
+        this.translateToCenter(size);
+      } else {
+        this.translateToCenter();
+      }
+      this.translateOffsetX =
+        this.translateOffsetY = 0;
+      this.scaleOffsetX = 
+        this.scaleOffsetY = 1;
+      this.clear();
+      this.viz.resize(width, height, this);
+    },
+    translate: function(x, y, disablePlot) {
+      var sx = this.scaleOffsetX,
+          sy = this.scaleOffsetY;
+      this.translateOffsetX += x*sx;
+      this.translateOffsetY += y*sy;
+      this.getCtx().translate(x, y);
+      !disablePlot && this.plot();
+    },
+    scale: function(x, y, disablePlot) {
+      this.scaleOffsetX *= x;
+      this.scaleOffsetY *= y;
+      this.getCtx().scale(x, y);
+      !disablePlot && this.plot();
+    },
+    clear: function(){
+      var size = this.getSize(),
+          ox = this.translateOffsetX,
+          oy = this.translateOffsetY,
+          sx = this.scaleOffsetX,
+          sy = this.scaleOffsetY;
+      this.getCtx().clearRect((-size.width / 2 - ox) * 1/sx, 
+                              (-size.height / 2 - oy) * 1/sy, 
+                              size.width * 1/sx, size.height * 1/sy);
+    },
+    plot: function() {
+      this.clear();
+      this.viz.plot(this);
+    }
+  });
+  //background canvases
+  //TODO(nico): document this!
+  Canvas.Background = {};
+  Canvas.Background.Circles = new Class({
+    initialize: function(viz, options) {
+      this.viz = viz;
+      this.config = $.merge({
+        idSuffix: '-bkcanvas',
+        levelDistance: 100,
+        numberOfCircles: 6,
+        CanvasStyles: {},
+        offset: 0
+      }, options);
+    },
+    resize: function(width, height, base) {
+      this.plot(base);
+    },
+    plot: function(base) {
+      var canvas = base.canvas,
+          ctx = base.getCtx(),
+          conf = this.config,
+          styles = conf.CanvasStyles;
+      //set canvas styles
+      for(var s in styles) ctx[s] = styles[s];
+      var n = conf.numberOfCircles,
+          rho = conf.levelDistance;
+      for(var i=1; i<=n; i++) {
+        ctx.beginPath();
+        ctx.arc(0, 0, rho * i, 0, 2 * Math.PI, false);
+        ctx.stroke();
+        ctx.closePath();
+      }
+      //TODO(nico): print labels too!
+    }
+  });
+})();
+
+
+/*
+ * File: Polar.js
+ * 
+ * Defines the <Polar> class.
+ *
+ * Description:
+ *
+ * The <Polar> class, just like the <Complex> class, is used by the <Hypertree>, <ST> and <RGraph> as a 2D point representation.
+ *
+ * See also:
+ *
+ * <http://en.wikipedia.org/wiki/Polar_coordinates>
+ *
+*/
+
+/*
+   Class: Polar
+
+   A multi purpose polar representation.
+
+   Description:
+ 
+   The <Polar> class, just like the <Complex> class, is used by the <Hypertree>, <ST> and <RGraph> as a 2D point representation.
+ 
+   See also:
+ 
+   <http://en.wikipedia.org/wiki/Polar_coordinates>
+ 
+   Parameters:
+
+      theta - An angle.
+      rho - The norm.
+*/
+
+var Polar = function(theta, rho) {
+  this.theta = theta || 0;
+  this.rho = rho || 0;
+};
+
+$jit.Polar = Polar;
+
+Polar.prototype = {
+    /*
+       Method: getc
+    
+       Returns a complex number.
+    
+       Parameters:
+
+       simple - _optional_ If *true*, this method will return only an object holding x and y properties and not a <Complex> instance. Default's *false*.
+
+      Returns:
+    
+          A complex number.
+    */
+    getc: function(simple) {
+        return this.toComplex(simple);
+    },
+
+    /*
+       Method: getp
+    
+       Returns a <Polar> representation.
+    
+       Returns:
+    
+          A variable in polar coordinates.
+    */
+    getp: function() {
+        return this;
+    },
+
+
+    /*
+       Method: set
+    
+       Sets a number.
+
+       Parameters:
+
+       v - A <Complex> or <Polar> instance.
+    
+    */
+    set: function(v) {
+        v = v.getp();
+        this.theta = v.theta; this.rho = v.rho;
+    },
+
+    /*
+       Method: setc
+    
+       Sets a <Complex> number.
+
+       Parameters:
+
+       x - A <Complex> number real part.
+       y - A <Complex> number imaginary part.
+    
+    */
+    setc: function(x, y) {
+        this.rho = Math.sqrt(x * x + y * y);
+        this.theta = Math.atan2(y, x);
+        if(this.theta < 0) this.theta += Math.PI * 2;
+    },
+
+    /*
+       Method: setp
+    
+       Sets a polar number.
+
+       Parameters:
+
+       theta - A <Polar> number angle property.
+       rho - A <Polar> number rho property.
+    
+    */
+    setp: function(theta, rho) {
+        this.theta = theta; 
+        this.rho = rho;
+    },
+
+    /*
+       Method: clone
+    
+       Returns a copy of the current object.
+    
+       Returns:
+    
+          A copy of the real object.
+    */
+    clone: function() {
+        return new Polar(this.theta, this.rho);
+    },
+
+    /*
+       Method: toComplex
+    
+        Translates from polar to cartesian coordinates and returns a new <Complex> instance.
+    
+        Parameters:
+
+        simple - _optional_ If *true* this method will only return an object with x and y properties (and not the whole <Complex> instance). Default's *false*.
+ 
+        Returns:
+    
+          A new <Complex> instance.
+    */
+    toComplex: function(simple) {
+        var x = Math.cos(this.theta) * this.rho;
+        var y = Math.sin(this.theta) * this.rho;
+        if(simple) return { 'x': x, 'y': y};
+        return new Complex(x, y);
+    },
+
+    /*
+       Method: add
+    
+        Adds two <Polar> instances.
+    
+       Parameters:
+
+       polar - A <Polar> number.
+
+       Returns:
+    
+          A new Polar instance.
+    */
+    add: function(polar) {
+        return new Polar(this.theta + polar.theta, this.rho + polar.rho);
+    },
+    
+    /*
+       Method: scale
+    
+        Scales a polar norm.
+    
+        Parameters:
+
+        number - A scale factor.
+        
+        Returns:
+    
+          A new Polar instance.
+    */
+    scale: function(number) {
+        return new Polar(this.theta, this.rho * number);
+    },
+    
+    /*
+       Method: equals
+    
+       Comparison method.
+
+       Returns *true* if the theta and rho properties are equal.
+
+       Parameters:
+
+       c - A <Polar> number.
+
+       Returns:
+
+       *true* if the theta and rho parameters for these objects are equal. *false* otherwise.
+    */
+    equals: function(c) {
+        return this.theta == c.theta && this.rho == c.rho;
+    },
+    
+    /*
+       Method: $add
+    
+        Adds two <Polar> instances affecting the current object.
+    
+       Paramters:
+
+       polar - A <Polar> instance.
+
+       Returns:
+    
+          The changed object.
+    */
+    $add: function(polar) {
+        this.theta = this.theta + polar.theta; this.rho += polar.rho;
+        return this;
+    },
+
+    /*
+       Method: $madd
+    
+        Adds two <Polar> instances affecting the current object. The resulting theta angle is modulo 2pi.
+    
+       Parameters:
+
+       polar - A <Polar> instance.
+
+       Returns:
+    
+          The changed object.
+    */
+    $madd: function(polar) {
+        this.theta = (this.theta + polar.theta) % (Math.PI * 2); this.rho += polar.rho;
+        return this;
+    },
+
+    
+    /*
+       Method: $scale
+    
+        Scales a polar instance affecting the object.
+    
+      Parameters:
+
+      number - A scaling factor.
+
+      Returns:
+    
+          The changed object.
+    */
+    $scale: function(number) {
+        this.rho *= number;
+        return this;
+    },
+    
+    /*
+      Method: isZero
+   
+      Returns *true* if the number is zero.
+   
+   */
+    isZero: function () {
+      var almostZero = 0.0001, abs = Math.abs;
+      return abs(this.theta) < almostZero && abs(this.rho) < almostZero;
+    },
+
+    /*
+       Method: interpolate
+    
+        Calculates a polar interpolation between two points at a given delta moment.
+
+        Parameters:
+      
+        elem - A <Polar> instance.
+        delta - A delta factor ranging [0, 1].
+    
+       Returns:
+    
+          A new <Polar> instance representing an interpolation between _this_ and _elem_
+    */
+    interpolate: function(elem, delta) {
+        var pi = Math.PI, pi2 = pi * 2;
+        var ch = function(t) {
+            var a =  (t < 0)? (t % pi2) + pi2 : t % pi2;
+            return a;
+        };
+        var tt = this.theta, et = elem.theta;
+        var sum, diff = Math.abs(tt - et);
+        if(diff == pi) {
+          if(tt > et) {
+            sum = ch((et + ((tt - pi2) - et) * delta)) ;
+          } else {
+            sum = ch((et - pi2 + (tt - (et)) * delta));
+          }
+        } else if(diff >= pi) {
+          if(tt > et) {
+            sum = ch((et + ((tt - pi2) - et) * delta)) ;
+          } else {
+            sum = ch((et - pi2 + (tt - (et - pi2)) * delta));
+          }
+        } else {  
+          sum = ch((et + (tt - et) * delta)) ;
+        }
+        var r = (this.rho - elem.rho) * delta + elem.rho;
+        return {
+          'theta': sum,
+          'rho': r
+        };
+    }
+};
+
+
+var $P = function(a, b) { return new Polar(a, b); };
+
+Polar.KER = $P(0, 0);
+
+
+
+/*
+ * File: Complex.js
+ * 
+ * Defines the <Complex> class.
+ *
+ * Description:
+ *
+ * The <Complex> class, just like the <Polar> class, is used by the <Hypertree>, <ST> and <RGraph> as a 2D point representation.
+ *
+ * See also:
+ *
+ * <http://en.wikipedia.org/wiki/Complex_number>
+ *
+*/
+
+/*
+   Class: Complex
+    
+   A multi-purpose Complex Class with common methods.
+ 
+   Description:
+ 
+   The <Complex> class, just like the <Polar> class, is used by the <Hypertree>, <ST> and <RGraph> as a 2D point representation.
+ 
+   See also:
+ 
+   <http://en.wikipedia.org/wiki/Complex_number>
+
+   Parameters:
+
+   x - _optional_ A Complex number real part.
+   y - _optional_ A Complex number imaginary part.
+ 
+*/
+
+var Complex = function(x, y) {
+  this.x = x || 0;
+  this.y = y || 0;
+};
+
+$jit.Complex = Complex;
+
+Complex.prototype = {
+    /*
+       Method: getc
+    
+       Returns a complex number.
+    
+       Returns:
+    
+          A complex number.
+    */
+    getc: function() {
+        return this;
+    },
+
+    /*
+       Method: getp
+    
+       Returns a <Polar> representation of this number.
+    
+       Parameters:
+
+       simple - _optional_ If *true*, this method will return only an object holding theta and rho properties and not a <Polar> instance. Default's *false*.
+
+       Returns:
+    
+          A variable in <Polar> coordinates.
+    */
+    getp: function(simple) {
+        return this.toPolar(simple);
+    },
+
+
+    /*
+       Method: set
+    
+       Sets a number.
+
+       Parameters:
+
+       c - A <Complex> or <Polar> instance.
+    
+    */
+    set: function(c) {
+      c = c.getc(true);
+      this.x = c.x; 
+      this.y = c.y;
+    },
+
+    /*
+       Method: setc
+    
+       Sets a complex number.
+
+       Parameters:
+
+       x - A <Complex> number Real part.
+       y - A <Complex> number Imaginary part.
+    
+    */
+    setc: function(x, y) {
+        this.x = x; 
+        this.y = y;
+    },
+
+    /*
+       Method: setp
+    
+       Sets a polar number.
+
+       Parameters:
+
+       theta - A <Polar> number theta property.
+       rho - A <Polar> number rho property.
+    
+    */
+    setp: function(theta, rho) {
+        this.x = Math.cos(theta) * rho;
+        this.y = Math.sin(theta) * rho;
+    },
+
+    /*
+       Method: clone
+    
+       Returns a copy of the current object.
+    
+       Returns:
+    
+          A copy of the real object.
+    */
+    clone: function() {
+        return new Complex(this.x, this.y);
+    },
+
+    /*
+       Method: toPolar
+    
+       Transforms cartesian to polar coordinates.
+    
+       Parameters:
+
+       simple - _optional_ If *true* this method will only return an object with theta and rho properties (and not the whole <Polar> instance). Default's *false*.
+       
+       Returns:
+    
+          A new <Polar> instance.
+    */
+    
+    toPolar: function(simple) {
+        var rho = this.norm();
+        var atan = Math.atan2(this.y, this.x);
+        if(atan < 0) atan += Math.PI * 2;
+        if(simple) return { 'theta': atan, 'rho': rho };
+        return new Polar(atan, rho);
+    },
+    /*
+       Method: norm
+    
+       Calculates a <Complex> number norm.
+    
+       Returns:
+    
+          A real number representing the complex norm.
+    */
+    norm: function () {
+        return Math.sqrt(this.squaredNorm());
+    },
+    
+    /*
+       Method: squaredNorm
+    
+       Calculates a <Complex> number squared norm.
+    
+       Returns:
+    
+          A real number representing the complex squared norm.
+    */
+    squaredNorm: function () {
+        return this.x*this.x + this.y*this.y;
+    },
+
+    /*
+       Method: add
+    
+       Returns the result of adding two complex numbers.
+       
+       Does not alter the original object.
+
+       Parameters:
+    
+          pos - A <Complex> instance.
+    
+       Returns:
+    
+         The result of adding two complex numbers.
+    */
+    add: function(pos) {
+        return new Complex(this.x + pos.x, this.y + pos.y);
+    },
+
+    /*
+       Method: prod
+    
+       Returns the result of multiplying two <Complex> numbers.
+       
+       Does not alter the original object.
+
+       Parameters:
+    
+          pos - A <Complex> instance.
+    
+       Returns:
+    
+         The result of multiplying two complex numbers.
+    */
+    prod: function(pos) {
+        return new Complex(this.x*pos.x - this.y*pos.y, this.y*pos.x + this.x*pos.y);
+    },
+
+    /*
+       Method: conjugate
+    
+       Returns the conjugate of this <Complex> number.
+
+       Does not alter the original object.
+
+       Returns:
+    
+         The conjugate of this <Complex> number.
+    */
+    conjugate: function() {
+        return new Complex(this.x, -this.y);
+    },
+
+
+    /*
+       Method: scale
+    
+       Returns the result of scaling a <Complex> instance.
+       
+       Does not alter the original object.
+
+       Parameters:
+    
+          factor - A scale factor.
+    
+       Returns:
+    
+         The result of scaling this complex to a factor.
+    */
+    scale: function(factor) {
+        return new Complex(this.x * factor, this.y * factor);
+    },
+
+    /*
+       Method: equals
+    
+       Comparison method.
+
+       Returns *true* if both real and imaginary parts are equal.
+
+       Parameters:
+
+       c - A <Complex> instance.
+
+       Returns:
+
+       A boolean instance indicating if both <Complex> numbers are equal.
+    */
+    equals: function(c) {
+        return this.x == c.x && this.y == c.y;
+    },
+
+    /*
+       Method: $add
+    
+       Returns the result of adding two <Complex> numbers.
+       
+       Alters the original object.
+
+       Parameters:
+    
+          pos - A <Complex> instance.
+    
+       Returns:
+    
+         The result of adding two complex numbers.
+    */
+    $add: function(pos) {
+        this.x += pos.x; this.y += pos.y;
+        return this;    
+    },
+    
+    /*
+       Method: $prod
+    
+       Returns the result of multiplying two <Complex> numbers.
+       
+       Alters the original object.
+
+       Parameters:
+    
+          pos - A <Complex> instance.
+    
+       Returns:
+    
+         The result of multiplying two complex numbers.
+    */
+    $prod:function(pos) {
+        var x = this.x, y = this.y;
+        this.x = x*pos.x - y*pos.y;
+        this.y = y*pos.x + x*pos.y;
+        return this;
+    },
+    
+    /*
+       Method: $conjugate
+    
+       Returns the conjugate for this <Complex>.
+       
+       Alters the original object.
+
+       Returns:
+    
+         The conjugate for this complex.
+    */
+    $conjugate: function() {
+        this.y = -this.y;
+        return this;
+    },
+    
+    /*
+       Method: $scale
+    
+       Returns the result of scaling a <Complex> instance.
+       
+       Alters the original object.
+
+       Parameters:
+    
+          factor - A scale factor.
+    
+       Returns:
+    
+         The result of scaling this complex to a factor.
+    */
+    $scale: function(factor) {
+        this.x *= factor; this.y *= factor;
+        return this;
+    },
+    
+    /*
+       Method: $div
+    
+       Returns the division of two <Complex> numbers.
+       
+       Alters the original object.
+
+       Parameters:
+    
+          pos - A <Complex> number.
+    
+       Returns:
+    
+         The result of scaling this complex to a factor.
+    */
+    $div: function(pos) {
+        var x = this.x, y = this.y;
+        var sq = pos.squaredNorm();
+        this.x = x * pos.x + y * pos.y; this.y = y * pos.x - x * pos.y;
+        return this.$scale(1 / sq);
+    },
+
+    /*
+      Method: isZero
+   
+      Returns *true* if the number is zero.
+   
+   */
+    isZero: function () {
+      var almostZero = 0.0001, abs = Math.abs;
+      return abs(this.x) < almostZero && abs(this.y) < almostZero;
+    }
+};
+
+var $C = function(a, b) { return new Complex(a, b); };
+
+Complex.KER = $C(0, 0);
+
+
+
+/*
+ * File: Graph.js
+ *
+*/
+
+/*
+ Class: Graph
+
+ A Graph Class that provides useful manipulation functions. You can find more manipulation methods in the <Graph.Util> object.
+
+ An instance of this class can be accessed by using the *graph* parameter of any tree or graph visualization.
+ 
+ Example:
+
+ (start code js)
+   //create new visualization
+   var viz = new $jit.Viz(options);
+   //load JSON data
+   viz.loadJSON(json);
+   //access model
+   viz.graph; //<Graph> instance
+ (end code)
+ 
+ Implements:
+ 
+ The following <Graph.Util> methods are implemented in <Graph>
+ 
+  - <Graph.Util.getNode>
+  - <Graph.Util.eachNode>
+  - <Graph.Util.computeLevels>
+  - <Graph.Util.eachBFS>
+  - <Graph.Util.clean>
+  - <Graph.Util.getClosestNodeToPos>
+  - <Graph.Util.getClosestNodeToOrigin>
+ 
+*/  
+
+$jit.Graph = new Class({
+
+  initialize: function(opt, Node, Edge, Label) {
+    var innerOptions = {
+    'klass': Complex,
+    'Node': {}
+    };
+    this.Node = Node;
+    this.Edge = Edge;
+    this.Label = Label;
+    this.opt = $.merge(innerOptions, opt || {});
+    this.nodes = {};
+    this.edges = {};
+    
+    //add nodeList methods
+    var that = this;
+    this.nodeList = {};
+    for(var p in Accessors) {
+      that.nodeList[p] = (function(p) {
+        return function() {
+          var args = Array.prototype.slice.call(arguments);
+          that.eachNode(function(n) {
+            n[p].apply(n, args);
+          });
+        };
+      })(p);
+    }
+
+ },
+
+/*
+     Method: getNode
+    
+     Returns a <Graph.Node> by *id*.
+
+     Parameters:
+
+     id - (string) A <Graph.Node> id.
+
+     Example:
+
+     (start code js)
+       var node = graph.getNode('nodeId');
+     (end code)
+*/  
+ getNode: function(id) {
+    if(this.hasNode(id)) return this.nodes[id];
+    return false;
+ },
+
+ /*
+     Method: get
+    
+     An alias for <Graph.Util.getNode>. Returns a node by *id*.
+    
+     Parameters:
+    
+     id - (string) A <Graph.Node> id.
+    
+     Example:
+    
+     (start code js)
+       var node = graph.get('nodeId');
+     (end code)
+*/  
+  get: function(id) {
+    return this.getNode(id);
+  },
+
+ /*
+   Method: getByName
+  
+   Returns a <Graph.Node> by *name*.
+  
+   Parameters:
+  
+   name - (string) A <Graph.Node> name.
+  
+   Example:
+  
+   (start code js)
+     var node = graph.getByName('someName');
+   (end code)
+  */  
+  getByName: function(name) {
+    for(var id in this.nodes) {
+      var n = this.nodes[id];
+      if(n.name == name) return n;
+    }
+    return false;
+  },
+
+/*
+   Method: getAdjacence
+  
+   Returns a <Graph.Adjacence> object connecting nodes with ids *id* and *id2*.
+
+   Parameters:
+
+   id - (string) A <Graph.Node> id.
+   id2 - (string) A <Graph.Node> id.
+*/  
+  getAdjacence: function (id, id2) {
+    if(id in this.edges) {
+      return this.edges[id][id2];
+    }
+    return false;
+ },
+
+    /*
+     Method: addNode
+    
+     Adds a node.
+     
+     Parameters:
+    
+      obj - An object with the properties described below
+
+      id - (string) A node id
+      name - (string) A node's name
+      data - (object) A node's data hash
+
+    See also:
+    <Graph.Node>
+
+  */  
+  addNode: function(obj) { 
+   if(!this.nodes[obj.id]) {  
+     var edges = this.edges[obj.id] = {};
+     this.nodes[obj.id] = new Graph.Node($.extend({
+        'id': obj.id,
+        'name': obj.name,
+        'data': $.merge(obj.data || {}, {}),
+        'adjacencies': edges 
+      }, this.opt.Node), 
+      this.opt.klass, 
+      this.Node, 
+      this.Edge,
+      this.Label);
+    }
+    return this.nodes[obj.id];
+  },
+  
+    /*
+     Method: addAdjacence
+    
+     Connects nodes specified by *obj* and *obj2*. If not found, nodes are created.
+     
+     Parameters:
+    
+      obj - (object) A <Graph.Node> object.
+      obj2 - (object) Another <Graph.Node> object.
+      data - (object) A data object. Used to store some extra information in the <Graph.Adjacence> object created.
+
+    See also:
+
+    <Graph.Node>, <Graph.Adjacence>
+    */  
+  addAdjacence: function (obj, obj2, data) {
+    if(!this.hasNode(obj.id)) { this.addNode(obj); }
+    if(!this.hasNode(obj2.id)) { this.addNode(obj2); }
+    obj = this.nodes[obj.id]; obj2 = this.nodes[obj2.id];
+    if(!obj.adjacentTo(obj2)) {
+      var adjsObj = this.edges[obj.id] = this.edges[obj.id] || {};
+      var adjsObj2 = this.edges[obj2.id] = this.edges[obj2.id] || {};
+      adjsObj[obj2.id] = adjsObj2[obj.id] = new Graph.Adjacence(obj, obj2, data, this.Edge, this.Label);
+      return adjsObj[obj2.id];
+    }
+    return this.edges[obj.id][obj2.id];
+ },
+
+    /*
+     Method: removeNode
+    
+     Removes a <Graph.Node> matching the specified *id*.
+
+     Parameters:
+
+     id - (string) A node's id.
+
+    */  
+  removeNode: function(id) {
+    if(this.hasNode(id)) {
+      delete this.nodes[id];
+      var adjs = this.edges[id];
+      for(var to in adjs) {
+        delete this.edges[to][id];
+      }
+      delete this.edges[id];
+    }
+  },
+  
+/*
+     Method: removeAdjacence
+    
+     Removes a <Graph.Adjacence> matching *id1* and *id2*.
+
+     Parameters:
+
+     id1 - (string) A <Graph.Node> id.
+     id2 - (string) A <Graph.Node> id.
+*/  
+  removeAdjacence: function(id1, id2) {
+    delete this.edges[id1][id2];
+    delete this.edges[id2][id1];
+  },
+
+   /*
+     Method: hasNode
+    
+     Returns a boolean indicating if the node belongs to the <Graph> or not.
+     
+     Parameters:
+    
+        id - (string) Node id.
+   */  
+  hasNode: function(id) {
+    return id in this.nodes;
+  },
+  
+  /*
+    Method: empty
+
+    Empties the Graph
+
+  */
+  empty: function() { this.nodes = {}; this.edges = {};}
+
+});
+
+var Graph = $jit.Graph;
+
+/*
+ Object: Accessors
+ 
+ Defines a set of methods for data, canvas and label styles manipulation implemented by <Graph.Node> and <Graph.Adjacence> instances.
+ 
+ */
+var Accessors;
+
+(function () {
+  var getDataInternal = function(prefix, prop, type, force, prefixConfig) {
+    var data;
+    type = type || 'current';
+    prefix = "$" + (prefix ? prefix + "-" : "");
+
+    if(type == 'current') {
+      data = this.data;
+    } else if(type == 'start') {
+      data = this.startData;
+    } else if(type == 'end') {
+      data = this.endData;
+    }
+
+    var dollar = prefix + prop;
+
+    if(force) {
+      return data[dollar];
+    }
+
+    if(!this.Config.overridable)
+      return prefixConfig[prop] || 0;
+
+    return (dollar in data) ?
+      data[dollar] : ((dollar in this.data) ? this.data[dollar] : (prefixConfig[prop] || 0));
+  }
+
+  var setDataInternal = function(prefix, prop, value, type) {
+    type = type || 'current';
+    prefix = '$' + (prefix ? prefix + '-' : '');
+
+    var data;
+
+    if(type == 'current') {
+      data = this.data;
+    } else if(type == 'start') {
+      data = this.startData;
+    } else if(type == 'end') {
+      data = this.endData;
+    }
+
+    data[prefix + prop] = value;
+  }
+
+  var removeDataInternal = function(prefix, properties) {
+    prefix = '$' + (prefix ? prefix + '-' : '');
+    var that = this;
+    $.each(properties, function(prop) {
+      var pref = prefix + prop;
+      delete that.data[pref];
+      delete that.endData[pref];
+      delete that.startData[pref];
+    });
+  }
+
+  Accessors = {
+    /*
+    Method: getData
+
+    Returns the specified data value property.
+    This is useful for querying special/reserved <Graph.Node> data properties
+    (i.e dollar prefixed properties).
+
+    Parameters:
+
+      prop  - (string) The name of the property. The dollar sign is not needed. For
+              example *getData(width)* will return *data.$width*.
+      type  - (string) The type of the data property queried. Default's "current". You can access *start* and *end* 
+              data properties also. These properties are used when making animations.
+      force - (boolean) Whether to obtain the true value of the property (equivalent to
+              *data.$prop*) or to check for *node.overridable = true* first.
+
+    Returns:
+
+      The value of the dollar prefixed property or the global Node/Edge property
+      value if *overridable=false*
+
+    Example:
+    (start code js)
+     node.getData('width'); //will return node.data.$width if Node.overridable=true;
+    (end code)
+    */
+    getData: function(prop, type, force) {
+      return getDataInternal.call(this, "", prop, type, force, this.Config);
+    },
+
+
+    /*
+    Method: setData
+
+    Sets the current data property with some specific value.
+    This method is only useful for reserved (dollar prefixed) properties.
+
+    Parameters:
+
+      prop  - (string) The name of the property. The dollar sign is not necessary. For
+              example *setData(width)* will set *data.$width*.
+      value - (mixed) The value to store.
+      type  - (string) The type of the data property to store. Default's "current" but
+              can also be "start" or "end".
+
+    Example:
+    
+    (start code js)
+     node.setData('width', 30);
+    (end code)
+    
+    If we were to make an animation of a node/edge width then we could do
+    
+    (start code js)
+      var node = viz.getNode('nodeId');
+      //set start and end values
+      node.setData('width', 10, 'start');
+      node.setData('width', 30, 'end');
+      //will animate nodes width property
+      viz.fx.animate({
+        modes: ['node-property:width'],
+        duration: 1000
+      });
+    (end code)
+    */
+    setData: function(prop, value, type) {
+      setDataInternal.call(this, "", prop, value, type);
+    },
+
+    /*
+    Method: setDataset
+
+    Convenience method to set multiple data values at once.
+    
+    Parameters:
+    
+    types - (array|string) A set of 'current', 'end' or 'start' values.
+    obj - (object) A hash containing the names and values of the properties to be altered.
+
+    Example:
+    (start code js)
+      node.setDataset(['current', 'end'], {
+        'width': [100, 5],
+        'color': ['#fff', '#ccc']
+      });
+      //...or also
+      node.setDataset('end', {
+        'width': 5,
+        'color': '#ccc'
+      });
+    (end code)
+    
+    See also: 
+    
+    <Accessors.setData>
+    
+    */
+    setDataset: function(types, obj) {
+      types = $.splat(types);
+      for(var attr in obj) {
+        for(var i=0, val = $.splat(obj[attr]), l=types.length; i<l; i++) {
+          this.setData(attr, val[i], types[i]);
+        }
+      }
+    },
+    
+    /*
+    Method: removeData
+
+    Remove data properties.
+
+    Parameters:
+
+    One or more property names as arguments. The dollar sign is not needed.
+
+    Example:
+    (start code js)
+    node.removeData('width'); //now the default width value is returned
+    (end code)
+    */
+    removeData: function() {
+      removeDataInternal.call(this, "", Array.prototype.slice.call(arguments));
+    },
+
+    /*
+    Method: getCanvasStyle
+
+    Returns the specified canvas style data value property. This is useful for
+    querying special/reserved <Graph.Node> canvas style data properties (i.e.
+    dollar prefixed properties that match with $canvas-<name of canvas style>).
+
+    Parameters:
+
+      prop  - (string) The name of the property. The dollar sign is not needed. For
+              example *getCanvasStyle(shadowBlur)* will return *data[$canvas-shadowBlur]*.
+      type  - (string) The type of the data property queried. Default's *current*. You can access *start* and *end* 
+              data properties also.
+              
+    Example:
+    (start code js)
+      node.getCanvasStyle('shadowBlur');
+    (end code)
+    
+    See also:
+    
+    <Accessors.getData>
+    */
+    getCanvasStyle: function(prop, type, force) {
+      return getDataInternal.call(
+          this, 'canvas', prop, type, force, this.Config.CanvasStyles);
+    },
+
+    /*
+    Method: setCanvasStyle
+
+    Sets the canvas style data property with some specific value.
+    This method is only useful for reserved (dollar prefixed) properties.
+    
+    Parameters:
+    
+    prop - (string) Name of the property. Can be any canvas property like 'shadowBlur', 'shadowColor', 'strokeStyle', etc.
+    value - (mixed) The value to set to the property.
+    type - (string) Default's *current*. Whether to set *start*, *current* or *end* type properties.
+    
+    Example:
+    
+    (start code js)
+     node.setCanvasStyle('shadowBlur', 30);
+    (end code)
+    
+    If we were to make an animation of a node/edge shadowBlur canvas style then we could do
+    
+    (start code js)
+      var node = viz.getNode('nodeId');
+      //set start and end values
+      node.setCanvasStyle('shadowBlur', 10, 'start');
+      node.setCanvasStyle('shadowBlur', 30, 'end');
+      //will animate nodes canvas style property for nodes
+      viz.fx.animate({
+        modes: ['node-style:shadowBlur'],
+        duration: 1000
+      });
+    (end code)
+    
+    See also:
+    
+    <Accessors.setData>.
+    */
+    setCanvasStyle: function(prop, value, type) {
+      setDataInternal.call(this, 'canvas', prop, value, type);
+    },
+
+    /*
+    Method: setCanvasStyles
+
+    Convenience method to set multiple styles at once.
+
+    Parameters:
+    
+    types - (array|string) A set of 'current', 'end' or 'start' values.
+    obj - (object) A hash containing the names and values of the properties to be altered.
+
+    See also:
+    
+    <Accessors.setDataset>.
+    */
+    setCanvasStyles: function(types, obj) {
+      types = $.splat(types);
+      for(var attr in obj) {
+        for(var i=0, val = $.splat(obj[attr]), l=types.length; i<l; i++) {
+          this.setCanvasStyle(attr, val[i], types[i]);
+        }
+      }
+    },
+
+    /*
+    Method: removeCanvasStyle
+
+    Remove canvas style properties from data.
+
+    Parameters:
+    
+    A variable number of canvas style strings.
+
+    See also:
+    
+    <Accessors.removeData>.
+    */
+    removeCanvasStyle: function() {
+      removeDataInternal.call(this, 'canvas', Array.prototype.slice.call(arguments));
+    },
+
+    /*
+    Method: getLabelData
+
+    Returns the specified label data value property. This is useful for
+    querying special/reserved <Graph.Node> label options (i.e.
+    dollar prefixed properties that match with $label-<name of label style>).
+
+    Parameters:
+
+      prop  - (string) The name of the property. The dollar sign prefix is not needed. For
+              example *getLabelData(size)* will return *data[$label-size]*.
+      type  - (string) The type of the data property queried. Default's *current*. You can access *start* and *end* 
+              data properties also.
+              
+    See also:
+    
+    <Accessors.getData>.
+    */
+    getLabelData: function(prop, type, force) {
+      return getDataInternal.call(
+          this, 'label', prop, type, force, this.Label);
+    },
+
+    /*
+    Method: setLabelData
+
+    Sets the current label data with some specific value.
+    This method is only useful for reserved (dollar prefixed) properties.
+
+    Parameters:
+    
+    prop - (string) Name of the property. Can be any canvas property like 'shadowBlur', 'shadowColor', 'strokeStyle', etc.
+    value - (mixed) The value to set to the property.
+    type - (string) Default's *current*. Whether to set *start*, *current* or *end* type properties.
+    
+    Example:
+    
+    (start code js)
+     node.setLabelData('size', 30);
+    (end code)
+    
+    If we were to make an animation of a node label size then we could do
+    
+    (start code js)
+      var node = viz.getNode('nodeId');
+      //set start and end values
+      node.setLabelData('size', 10, 'start');
+      node.setLabelData('size', 30, 'end');
+      //will animate nodes label size
+      viz.fx.animate({
+        modes: ['label-property:size'],
+        duration: 1000
+      });
+    (end code)
+    
+    See also:
+    
+    <Accessors.setData>.
+    */
+    setLabelData: function(prop, value, type) {
+      setDataInternal.call(this, 'label', prop, value, type);
+    },
+
+    /*
+    Method: setLabelDataset
+
+    Convenience function to set multiple label data at once.
+
+    Parameters:
+    
+    types - (array|string) A set of 'current', 'end' or 'start' values.
+    obj - (object) A hash containing the names and values of the properties to be altered.
+
+    See also:
+    
+    <Accessors.setDataset>.
+    */
+    setLabelDataset: function(types, obj) {
+      types = $.splat(types);
+      for(var attr in obj) {
+        for(var i=0, val = $.splat(obj[attr]), l=types.length; i<l; i++) {
+          this.setLabelData(attr, val[i], types[i]);
+        }
+      }
+    },
+
+    /*
+    Method: removeLabelData
+
+    Remove label properties from data.
+    
+    Parameters:
+    
+    A variable number of label property strings.
+
+    See also:
+    
+    <Accessors.removeData>.
+    */
+    removeLabelData: function() {
+      removeDataInternal.call(this, 'label', Array.prototype.slice.call(arguments));
+    }
+  };
+})();
+
+/*
+     Class: Graph.Node
+
+     A <Graph> node.
+     
+     Implements:
+     
+     <Accessors> methods.
+     
+     The following <Graph.Util> methods are implemented by <Graph.Node>
+     
+    - <Graph.Util.eachAdjacency>
+    - <Graph.Util.eachLevel>
+    - <Graph.Util.eachSubgraph>
+    - <Graph.Util.eachSubnode>
+    - <Graph.Util.anySubnode>
+    - <Graph.Util.getSubnodes>
+    - <Graph.Util.getParents>
+    - <Graph.Util.isDescendantOf>     
+*/
+Graph.Node = new Class({
+    
+  initialize: function(opt, klass, Node, Edge, Label) {
+    var innerOptions = {
+      'id': '',
+      'name': '',
+      'data': {},
+      'startData': {},
+      'endData': {},
+      'adjacencies': {},
+
+      'selected': false,
+      'drawn': false,
+      'exist': false,
+
+      'angleSpan': {
+        'begin': 0,
+        'end' : 0
+      },
+
+      'pos': new klass,
+      'startPos': new klass,
+      'endPos': new klass
+    };
+    
+    $.extend(this, $.extend(innerOptions, opt));
+    this.Config = this.Node = Node;
+    this.Edge = Edge;
+    this.Label = Label;
+  },
+
+    /*
+       Method: adjacentTo
+    
+       Indicates if the node is adjacent to the node specified by id
+
+       Parameters:
+    
+          id - (string) A node id.
+    
+       Example:
+       (start code js)
+        node.adjacentTo('nodeId') == true;
+       (end code)
+    */
+    adjacentTo: function(node) {
+        return node.id in this.adjacencies;
+    },
+
+    /*
+       Method: getAdjacency
+    
+       Returns a <Graph.Adjacence> object connecting the current <Graph.Node> and the node having *id* as id.
+
+       Parameters:
+    
+          id - (string) A node id.
+    */  
+    getAdjacency: function(id) {
+        return this.adjacencies[id];
+    },
+
+    /*
+      Method: getPos
+   
+      Returns the position of the node.
+  
+      Parameters:
+   
+         type - (string) Default's *current*. Possible values are "start", "end" or "current".
+   
+      Returns:
+   
+        A <Complex> or <Polar> instance.
+  
+      Example:
+      (start code js)
+       var pos = node.getPos('end');
+      (end code)
+   */
+   getPos: function(type) {
+       type = type || "current";
+       if(type == "current") {
+         return this.pos;
+       } else if(type == "end") {
+         return this.endPos;
+       } else if(type == "start") {
+         return this.startPos;
+       }
+   },
+   /*
+     Method: setPos
+  
+     Sets the node's position.
+  
+     Parameters:
+  
+        value - (object) A <Complex> or <Polar> instance.
+        type - (string) Default's *current*. Possible values are "start", "end" or "current".
+  
+     Example:
+     (start code js)
+      node.setPos(new $jit.Complex(0, 0), 'end');
+     (end code)
+  */
+  setPos: function(value, type) {
+      type = type || "current";
+      var pos;
+      if(type == "current") {
+        pos = this.pos;
+      } else if(type == "end") {
+        pos = this.endPos;
+      } else if(type == "start") {
+        pos = this.startPos;
+      }
+      pos.set(value);
+  }
+});
+
+Graph.Node.implement(Accessors);
+
+/*
+     Class: Graph.Adjacence
+
+     A <Graph> adjacence (or edge) connecting two <Graph.Nodes>.
+     
+     Implements:
+     
+     <Accessors> methods.
+
+     See also:
+
+     <Graph>, <Graph.Node>
+
+     Properties:
+     
+      nodeFrom - A <Graph.Node> connected by this edge.
+      nodeTo - Another  <Graph.Node> connected by this edge.
+      data - Node data property containing a hash (i.e {}) with custom options.
+*/
+Graph.Adjacence = new Class({
+  
+  initialize: function(nodeFrom, nodeTo, data, Edge, Label) {
+    this.nodeFrom = nodeFrom;
+    this.nodeTo = nodeTo;
+    this.data = data || {};
+    this.startData = {};
+    this.endData = {};
+    this.Config = this.Edge = Edge;
+    this.Label = Label;
+  }
+});
+
+Graph.Adjacence.implement(Accessors);
+
+/*
+   Object: Graph.Util
+
+   <Graph> traversal and processing utility object.
+   
+   Note:
+   
+   For your convenience some of these methods have also been appended to <Graph> and <Graph.Node> classes.
+*/
+Graph.Util = {
+    /*
+       filter
+    
+       For internal use only. Provides a filtering function based on flags.
+    */
+    filter: function(param) {
+        if(!param || !($.type(param) == 'string')) return function() { return true; };
+        var props = param.split(" ");
+        return function(elem) {
+            for(var i=0; i<props.length; i++) { 
+              if(elem[props[i]]) { 
+                return false; 
+              }
+            }
+            return true;
+        };
+    },
+    /*
+       Method: getNode
+    
+       Returns a <Graph.Node> by *id*.
+       
+       Also implemented by:
+       
+       <Graph>
+
+       Parameters:
+
+       graph - (object) A <Graph> instance.
+       id - (string) A <Graph.Node> id.
+
+       Example:
+
+       (start code js)
+         $jit.Graph.Util.getNode(graph, 'nodeid');
+         //or...
+         graph.getNode('nodeid');
+       (end code)
+    */
+    getNode: function(graph, id) {
+        return graph.nodes[id];
+    },
+    
+    /*
+       Method: eachNode
+    
+       Iterates over <Graph> nodes performing an *action*.
+       
+       Also implemented by:
+       
+       <Graph>.
+
+       Parameters:
+
+       graph - (object) A <Graph> instance.
+       action - (function) A callback function having a <Graph.Node> as first formal parameter.
+
+       Example:
+       (start code js)
+         $jit.Graph.Util.eachNode(graph, function(node) {
+          alert(node.name);
+         });
+         //or...
+         graph.eachNode(function(node) {
+           alert(node.name);
+         });
+       (end code)
+    */
+    eachNode: function(graph, action, flags) {
+        var filter = this.filter(flags);
+        for(var i in graph.nodes) {
+          if(filter(graph.nodes[i])) action(graph.nodes[i]);
+        } 
+    },
+    
+    /*
+      Method: each
+   
+      Iterates over <Graph> nodes performing an *action*. It's an alias for <Graph.Util.eachNode>.
+      
+      Also implemented by:
+      
+      <Graph>.
+  
+      Parameters:
+  
+      graph - (object) A <Graph> instance.
+      action - (function) A callback function having a <Graph.Node> as first formal parameter.
+  
+      Example:
+      (start code js)
+        $jit.Graph.Util.each(graph, function(node) {
+         alert(node.name);
+        });
+        //or...
+        graph.each(function(node) {
+          alert(node.name);
+        });
+      (end code)
+   */
+   each: function(graph, action, flags) {
+      this.eachNode(graph, action, flags); 
+   },
+
+ /*
+       Method: eachAdjacency
+    
+       Iterates over <Graph.Node> adjacencies applying the *action* function.
+       
+       Also implemented by:
+       
+       <Graph.Node>.
+
+       Parameters:
+
+       node - (object) A <Graph.Node>.
+       action - (function) A callback function having <Graph.Adjacence> as first formal parameter.
+
+       Example:
+       (start code js)
+         $jit.Graph.Util.eachAdjacency(node, function(adj) {
+          alert(adj.nodeTo.name);
+         });
+         //or...
+         node.eachAdjacency(function(adj) {
+           alert(adj.nodeTo.name);
+         });
+       (end code)
+    */
+    eachAdjacency: function(node, action, flags) {
+        var adj = node.adjacencies, filter = this.filter(flags);
+        for(var id in adj) {
+          var a = adj[id];
+          if(filter(a)) {
+            if(a.nodeFrom != node) {
+              var tmp = a.nodeFrom;
+              a.nodeFrom = a.nodeTo;
+              a.nodeTo = tmp;
+            }
+            action(a, id);
+          }
+        }
+    },
+
+     /*
+       Method: computeLevels
+    
+       Performs a BFS traversal setting the correct depth for each node.
+        
+       Also implemented by:
+       
+       <Graph>.
+       
+       Note:
+       
+       The depth of each node can then be accessed by 
+       >node._depth
+
+       Parameters:
+
+       graph - (object) A <Graph>.
+       id - (string) A starting node id for the BFS traversal.
+       startDepth - (optional|number) A minimum depth value. Default's 0.
+
+    */
+    computeLevels: function(graph, id, startDepth, flags) {
+        startDepth = startDepth || 0;
+        var filter = this.filter(flags);
+        this.eachNode(graph, function(elem) {
+            elem._flag = false;
+            elem._depth = -1;
+        }, flags);
+        var root = graph.getNode(id);
+        root._depth = startDepth;
+        var queue = [root];
+        while(queue.length != 0) {
+            var node = queue.pop();
+            node._flag = true;
+            this.eachAdjacency(node, function(adj) {
+                var n = adj.nodeTo;
+                if(n._flag == false && filter(n)) {
+                    if(n._depth < 0) n._depth = node._depth + 1 + startDepth;
+                    queue.unshift(n);
+                }
+            }, flags);
+        }
+    },
+
+    /*
+       Method: eachBFS
+    
+       Performs a BFS traversal applying *action* to each <Graph.Node>.
+       
+       Also implemented by:
+       
+       <Graph>.
+
+       Parameters:
+
+       graph - (object) A <Graph>.
+       id - (string) A starting node id for the BFS traversal.
+       action - (function) A callback function having a <Graph.Node> as first formal parameter.
+
+       Example:
+       (start code js)
+         $jit.Graph.Util.eachBFS(graph, 'mynodeid', function(node) {
+          alert(node.name);
+         });
+         //or...
+         graph.eachBFS('mynodeid', function(node) {
+           alert(node.name);
+         });
+       (end code)
+    */
+    eachBFS: function(graph, id, action, flags) {
+        var filter = this.filter(flags);
+        this.clean(graph);
+        var queue = [graph.getNode(id)];
+        while(queue.length != 0) {
+            var node = queue.pop();
+            node._flag = true;
+            action(node, node._depth);
+            this.eachAdjacency(node, function(adj) {
+                var n = adj.nodeTo;
+                if(n._flag == false && filter(n)) {
+                    n._flag = true;
+                    queue.unshift(n);
+                }
+            }, flags);
+        }
+    },
+    
+    /*
+       Method: eachLevel
+    
+       Iterates over a node's subgraph applying *action* to the nodes of relative depth between *levelBegin* and *levelEnd*.
+       
+       Also implemented by:
+       
+       <Graph.Node>.
+
+       Parameters:
+       
+       node - (object) A <Graph.Node>.
+       levelBegin - (number) A relative level value.
+       levelEnd - (number) A relative level value.
+       action - (function) A callback function having a <Graph.Node> as first formal parameter.
+
+    */
+    eachLevel: function(node, levelBegin, levelEnd, action, flags) {
+        var d = node._depth, filter = this.filter(flags), that = this;
+        levelEnd = levelEnd === false? Number.MAX_VALUE -d : levelEnd;
+        (function loopLevel(node, levelBegin, levelEnd) {
+            var d = node._depth;
+            if(d >= levelBegin && d <= levelEnd && filter(node)) action(node, d);
+            if(d < levelEnd) {
+                that.eachAdjacency(node, function(adj) {
+                    var n = adj.nodeTo;
+                    if(n._depth > d) loopLevel(n, levelBegin, levelEnd);
+                });
+            }
+        })(node, levelBegin + d, levelEnd + d);      
+    },
+
+    /*
+       Method: eachSubgraph
+    
+       Iterates over a node's children recursively.
+       
+       Also implemented by:
+       
+       <Graph.Node>.
+
+       Parameters:
+       node - (object) A <Graph.Node>.
+       action - (function) A callback function having a <Graph.Node> as first formal parameter.
+
+       Example:
+       (start code js)
+         $jit.Graph.Util.eachSubgraph(node, function(node) {
+           alert(node.name);
+         });
+         //or...
+         node.eachSubgraph(function(node) {
+           alert(node.name);
+         });
+       (end code)
+    */
+    eachSubgraph: function(node, action, flags) {
+      this.eachLevel(node, 0, false, action, flags);
+    },
+
+    /*
+       Method: eachSubnode
+    
+       Iterates over a node's children (without deeper recursion).
+       
+       Also implemented by:
+       
+       <Graph.Node>.
+       
+       Parameters:
+       node - (object) A <Graph.Node>.
+       action - (function) A callback function having a <Graph.Node> as first formal parameter.
+
+       Example:
+       (start code js)
+         $jit.Graph.Util.eachSubnode(node, function(node) {
+          alert(node.name);
+         });
+         //or...
+         node.eachSubnode(function(node) {
+           alert(node.name);
+         });
+       (end code)
+    */
+    eachSubnode: function(node, action, flags) {
+        this.eachLevel(node, 1, 1, action, flags);
+    },
+
+    /*
+       Method: anySubnode
+    
+       Returns *true* if any subnode matches the given condition.
+       
+       Also implemented by:
+       
+       <Graph.Node>.
+
+       Parameters:
+       node - (object) A <Graph.Node>.
+       cond - (function) A callback function returning a Boolean instance. This function has as first formal parameter a <Graph.Node>.
+
+       Example:
+       (start code js)
+         $jit.Graph.Util.anySubnode(node, function(node) { return node.name == "mynodename"; });
+         //or...
+         node.anySubnode(function(node) { return node.name == 'mynodename'; });
+       (end code)
+    */
+    anySubnode: function(node, cond, flags) {
+      var flag = false;
+      cond = cond || $.lambda(true);
+      var c = $.type(cond) == 'string'? function(n) { return n[cond]; } : cond;
+      this.eachSubnode(node, function(elem) {
+        if(c(elem)) flag = true;
+      }, flags);
+      return flag;
+    },
+  
+    /*
+       Method: getSubnodes
+    
+       Collects all subnodes for a specified node. 
+       The *level* parameter filters nodes having relative depth of *level* from the root node. 
+       
+       Also implemented by:
+       
+       <Graph.Node>.
+
+       Parameters:
+       node - (object) A <Graph.Node>.
+       level - (optional|number) Default's *0*. A starting relative depth for collecting nodes.
+
+       Returns:
+       An array of nodes.
+
+    */
+    getSubnodes: function(node, level, flags) {
+        var ans = [], that = this;
+        level = level || 0;
+        var levelStart, levelEnd;
+        if($.type(level) == 'array') {
+            levelStart = level[0];
+            levelEnd = level[1];
+        } else {
+            levelStart = level;
+            levelEnd = Number.MAX_VALUE - node._depth;
+        }
+        this.eachLevel(node, levelStart, levelEnd, function(n) {
+            ans.push(n);
+        }, flags);
+        return ans;
+    },
+  
+  
+    /*
+       Method: getParents
+    
+       Returns an Array of <Graph.Nodes> which are parents of the given node.
+       
+       Also implemented by:
+       
+       <Graph.Node>.
+
+       Parameters:
+       node - (object) A <Graph.Node>.
+
+       Returns:
+       An Array of <Graph.Nodes>.
+
+       Example:
+       (start code js)
+         var pars = $jit.Graph.Util.getParents(node);
+         //or...
+         var pars = node.getParents();
+         
+         if(pars.length > 0) {
+           //do stuff with parents
+         }
+       (end code)
+    */
+    getParents: function(node) {
+        var ans = [];
+        this.eachAdjacency(node, function(adj) {
+            var n = adj.nodeTo;
+            if(n._depth < node._depth) ans.push(n);
+        });
+        return ans;
+    },
+    
+    /*
+    Method: isDescendantOf
+ 
+    Returns a boolean indicating if some node is descendant of the node with the given id. 
+
+    Also implemented by:
+    
+    <Graph.Node>.
+    
+    
+    Parameters:
+    node - (object) A <Graph.Node>.
+    id - (string) A <Graph.Node> id.
+
+    Example:
+    (start code js)
+      $jit.Graph.Util.isDescendantOf(node, "nodeid"); //true|false
+      //or...
+      node.isDescendantOf('nodeid');//true|false
+    (end code)
+ */
+ isDescendantOf: function(node, id) {
+    if(node.id == id) return true;
+    var pars = this.getParents(node), ans = false;
+    for ( var i = 0; !ans && i < pars.length; i++) {
+    ans = ans || this.isDescendantOf(pars[i], id);
+  }
+    return ans;
+ },
+
+ /*
+     Method: clean
+  
+     Cleans flags from nodes.
+
+     Also implemented by:
+     
+     <Graph>.
+     
+     Parameters:
+     graph - A <Graph> instance.
+  */
+  clean: function(graph) { this.eachNode(graph, function(elem) { elem._flag = false; }); },
+  
+  /* 
+    Method: getClosestNodeToOrigin 
+  
+    Returns the closest node to the center of canvas.
+  
+    Also implemented by:
+    
+    <Graph>.
+    
+    Parameters:
+   
+     graph - (object) A <Graph> instance.
+     prop - (optional|string) Default's 'current'. A <Graph.Node> position property. Possible properties are 'start', 'current' or 'end'.
+  
+  */
+  getClosestNodeToOrigin: function(graph, prop, flags) {
+   return this.getClosestNodeToPos(graph, Polar.KER, prop, flags);
+  },
+  
+  /* 
+    Method: getClosestNodeToPos
+  
+    Returns the closest node to the given position.
+  
+    Also implemented by:
+    
+    <Graph>.
+    
+    Parameters:
+   
+     graph - (object) A <Graph> instance.
+     pos - (object) A <Complex> or <Polar> instance.
+     prop - (optional|string) Default's *current*. A <Graph.Node> position property. Possible properties are 'start', 'current' or 'end'.
+  
+  */
+  getClosestNodeToPos: function(graph, pos, prop, flags) {
+   var node = null;
+   prop = prop || 'current';
+   pos = pos && pos.getc(true) || Complex.KER;
+   var distance = function(a, b) {
+     var d1 = a.x - b.x, d2 = a.y - b.y;
+     return d1 * d1 + d2 * d2;
+   };
+   this.eachNode(graph, function(elem) {
+     node = (node == null || distance(elem.getPos(prop).getc(true), pos) < distance(
+         node.getPos(prop).getc(true), pos)) ? elem : node;
+   }, flags);
+   return node;
+  } 
+};
+
+//Append graph methods to <Graph>
+$.each(['get', 'getNode', 'each', 'eachNode', 'computeLevels', 'eachBFS', 'clean', 'getClosestNodeToPos', 'getClosestNodeToOrigin'], function(m) {
+  Graph.prototype[m] = function() {
+    return Graph.Util[m].apply(Graph.Util, [this].concat(Array.prototype.slice.call(arguments)));
+  };
+});
+
+//Append node methods to <Graph.Node>
+$.each(['eachAdjacency', 'eachLevel', 'eachSubgraph', 'eachSubnode', 'anySubnode', 'getSubnodes', 'getParents', 'isDescendantOf'], function(m) {
+  Graph.Node.prototype[m] = function() {
+    return Graph.Util[m].apply(Graph.Util, [this].concat(Array.prototype.slice.call(arguments)));
+  };
+});
+
+/*
+ * File: Graph.Op.js
+ *
+*/
+
+/*
+   Object: Graph.Op
+
+   Perform <Graph> operations like adding/removing <Graph.Nodes> or <Graph.Adjacences>, 
+   morphing a <Graph> into another <Graph>, contracting or expanding subtrees, etc.
+
+*/
+Graph.Op = {
+
+    options: {
+      type: 'nothing',
+      duration: 2000,
+      hideLabels: true,
+      fps:30
+    },
+    
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+
+    /*
+       Method: removeNode
+    
+       Removes one or more <Graph.Nodes> from the visualization. 
+       It can also perform several animations like fading sequentially, fading concurrently, iterating or replotting.
+
+       Parameters:
+    
+        node - (string|array) The node's id. Can also be an array having many ids.
+        opt - (object) Animation options. It's an object with optional properties described below
+        type - (string) Default's *nothing*. Type of the animation. Can be "nothing", "replot", "fade:seq",  "fade:con" or "iter".
+        duration - Described in <Options.Fx>.
+        fps - Described in <Options.Fx>.
+        transition - Described in <Options.Fx>.
+        hideLabels - (boolean) Default's *true*. Hide labels during the animation.
+   
+      Example:
+      (start code js)
+        var viz = new $jit.Viz(options);
+        viz.op.removeNode('nodeId', {
+          type: 'fade:seq',
+          duration: 1000,
+          hideLabels: false,
+          transition: $jit.Trans.Quart.easeOut
+        });
+        //or also
+        viz.op.removeNode(['someId', 'otherId'], {
+          type: 'fade:con',
+          duration: 1500
+        });
+      (end code)
+    */
+  
+    removeNode: function(node, opt) {
+        var viz = this.viz;
+        var options = $.merge(this.options, viz.controller, opt);
+        var n = $.splat(node);
+        var i, that, nodeObj;
+        switch(options.type) {
+            case 'nothing':
+                for(i=0; i<n.length; i++) viz.graph.removeNode(n[i]);
+                break;
+            
+            case 'replot':
+                this.removeNode(n, { type: 'nothing' });
+                viz.labels.clearLabels();
+                viz.refresh(true);
+                break;
+            
+            case 'fade:seq': case 'fade':
+                that = this;
+                //set alpha to 0 for nodes to remove.
+                for(i=0; i<n.length; i++) {
+                    nodeObj = viz.graph.getNode(n[i]);
+                    nodeObj.setData('alpha', 0, 'end');
+                }
+                viz.fx.animate($.merge(options, {
+                    modes: ['node-property:alpha'],
+                    onComplete: function() {
+                        that.removeNode(n, { type: 'nothing' });
+                        viz.labels.clearLabels();
+                        viz.reposition();
+                        viz.fx.animate($.merge(options, {
+                            modes: ['linear']
+                        }));
+                    }
+                }));
+                break;
+            
+            case 'fade:con':
+                that = this;
+                //set alpha to 0 for nodes to remove. Tag them for being ignored on computing positions.
+                for(i=0; i<n.length; i++) {
+                    nodeObj = viz.graph.getNode(n[i]);
+                    nodeObj.setData('alpha', 0, 'end');
+                    nodeObj.ignore = true;
+                }
+                viz.reposition();
+                viz.fx.animate($.merge(options, {
+                    modes: ['node-property:alpha', 'linear'],
+                    onComplete: function() {
+                        that.removeNode(n, { type: 'nothing' });
+                        options.onComplete && options.onComplete();
+                    }
+                }));
+                break;
+            
+            case 'iter':
+                that = this;
+                viz.fx.sequence({
+                    condition: function() { return n.length != 0; },
+                    step: function() { that.removeNode(n.shift(), { type: 'nothing' });  viz.labels.clearLabels(); },
+                    onComplete: function() { options.onComplete && options.onComplete(); },
+                    duration: Math.ceil(options.duration / n.length)
+                });
+                break;
+                
+            default: this.doError();
+        }
+    },
+    
+    /*
+       Method: removeEdge
+    
+       Removes one or more <Graph.Adjacences> from the visualization. 
+       It can also perform several animations like fading sequentially, fading concurrently, iterating or replotting.
+
+       Parameters:
+    
+       vertex - (array) An array having two strings which are the ids of the nodes connected by this edge (i.e ['id1', 'id2']). Can also be a two dimensional array holding many edges (i.e [['id1', 'id2'], ['id3', 'id4'], ...]).
+       opt - (object) Animation options. It's an object with optional properties described below
+       type - (string) Default's *nothing*. Type of the animation. Can be "nothing", "replot", "fade:seq",  "fade:con" or "iter".
+       duration - Described in <Options.Fx>.
+       fps - Described in <Options.Fx>.
+       transition - Described in <Options.Fx>.
+       hideLabels - (boolean) Default's *true*. Hide labels during the animation.
+   
+      Example:
+      (start code js)
+        var viz = new $jit.Viz(options);
+        viz.op.removeEdge(['nodeId', 'otherId'], {
+          type: 'fade:seq',
+          duration: 1000,
+          hideLabels: false,
+          transition: $jit.Trans.Quart.easeOut
+        });
+        //or also
+        viz.op.removeEdge([['someId', 'otherId'], ['id3', 'id4']], {
+          type: 'fade:con',
+          duration: 1500
+        });
+      (end code)
+    
+    */
+    removeEdge: function(vertex, opt) {
+        var viz = this.viz;
+        var options = $.merge(this.options, viz.controller, opt);
+        var v = ($.type(vertex[0]) == 'string')? [vertex] : vertex;
+        var i, that, adj;
+        switch(options.type) {
+            case 'nothing':
+                for(i=0; i<v.length; i++)   viz.graph.removeAdjacence(v[i][0], v[i][1]);
+                break;
+            
+            case 'replot':
+                this.removeEdge(v, { type: 'nothing' });
+                viz.refresh(true);
+                break;
+            
+            case 'fade:seq': case 'fade':
+                that = this;
+                //set alpha to 0 for edges to remove.
+                for(i=0; i<v.length; i++) {
+                    adj = viz.graph.getAdjacence(v[i][0], v[i][1]);
+                    if(adj) {
+                        adj.setData('alpha', 0,'end');
+                    }
+                }
+                viz.fx.animate($.merge(options, {
+                    modes: ['edge-property:alpha'],
+                    onComplete: function() {
+                        that.removeEdge(v, { type: 'nothing' });
+                        viz.reposition();
+                        viz.fx.animate($.merge(options, {
+                            modes: ['linear']
+                        }));
+                    }
+                }));
+                break;
+            
+            case 'fade:con':
+                that = this;
+                //set alpha to 0 for nodes to remove. Tag them for being ignored when computing positions.
+                for(i=0; i<v.length; i++) {
+                    adj = viz.graph.getAdjacence(v[i][0], v[i][1]);
+                    if(adj) {
+                        adj.setData('alpha',0 ,'end');
+                        adj.ignore = true;
+                    }
+                }
+                viz.reposition();
+                viz.fx.animate($.merge(options, {
+                    modes: ['edge-property:alpha', 'linear'],
+                    onComplete: function() {
+                        that.removeEdge(v, { type: 'nothing' });
+                        options.onComplete && options.onComplete();
+                    }
+                }));
+                break;
+            
+            case 'iter':
+                that = this;
+                viz.fx.sequence({
+                    condition: function() { return v.length != 0; },
+                    step: function() { that.removeEdge(v.shift(), { type: 'nothing' }); viz.labels.clearLabels(); },
+                    onComplete: function() { options.onComplete(); },
+                    duration: Math.ceil(options.duration / v.length)
+                });
+                break;
+                
+            default: this.doError();
+        }
+    },
+    
+    /*
+       Method: sum
+    
+       Adds a new graph to the visualization. 
+       The JSON graph (or tree) must at least have a common node with the current graph plotted by the visualization. 
+       The resulting graph can be defined as follows <http://mathworld.wolfram.com/GraphSum.html>
+
+       Parameters:
+    
+       json - (object) A json tree or graph structure. See also <Loader.loadJSON>.
+       opt - (object) Animation options. It's an object with optional properties described below
+       type - (string) Default's *nothing*. Type of the animation. Can be "nothing", "replot", "fade:seq",  "fade:con".
+       duration - Described in <Options.Fx>.
+       fps - Described in <Options.Fx>.
+       transition - Described in <Options.Fx>.
+       hideLabels - (boolean) Default's *true*. Hide labels during the animation.
+   
+      Example:
+      (start code js)
+        //...json contains a tree or graph structure...
+
+        var viz = new $jit.Viz(options);
+        viz.op.sum(json, {
+          type: 'fade:seq',
+          duration: 1000,
+          hideLabels: false,
+          transition: $jit.Trans.Quart.easeOut
+        });
+        //or also
+        viz.op.sum(json, {
+          type: 'fade:con',
+          duration: 1500
+        });
+      (end code)
+    
+    */
+    sum: function(json, opt) {
+        var viz = this.viz;
+        var options = $.merge(this.options, viz.controller, opt), root = viz.root;
+        var graph;
+        viz.root = opt.id || viz.root;
+        switch(options.type) {
+            case 'nothing':
+                graph = viz.construct(json);
+                graph.eachNode(function(elem) {
+                    elem.eachAdjacency(function(adj) {
+                        viz.graph.addAdjacence(adj.nodeFrom, adj.nodeTo, adj.data);
+                    });
+                });
+                break;
+            
+            case 'replot':
+                viz.refresh(true);
+                this.sum(json, { type: 'nothing' });
+                viz.refresh(true);
+                break;
+            
+            case 'fade:seq': case 'fade': case 'fade:con':
+                that = this;
+                graph = viz.construct(json);
+
+                //set alpha to 0 for nodes to add.
+                var fadeEdges = this.preprocessSum(graph);
+                var modes = !fadeEdges? ['node-property:alpha'] : ['node-property:alpha', 'edge-property:alpha'];
+                viz.reposition();
+                if(options.type != 'fade:con') {
+                    viz.fx.animate($.merge(options, {
+                        modes: ['linear'],
+                        onComplete: function() {
+                            viz.fx.animate($.merge(options, {
+                                modes: modes,
+                                onComplete: function() {
+                                    options.onComplete();
+                                }
+                            }));
+                        }
+                    }));
+                } else {
+                    viz.graph.eachNode(function(elem) {
+                        if (elem.id != root && elem.pos.isZero()) {
+                          elem.pos.set(elem.endPos); 
+                          elem.startPos.set(elem.endPos);
+                        }
+                    });
+                    viz.fx.animate($.merge(options, {
+                        modes: ['linear'].concat(modes)
+                    }));
+                }
+                break;
+
+            default: this.doError();
+        }
+    },
+    
+    /*
+       Method: morph
+    
+       This method will transform the current visualized graph into the new JSON representation passed in the method. 
+       The JSON object must at least have the root node in common with the current visualized graph.
+
+       Parameters:
+    
+       json - (object) A json tree or graph structure. See also <Loader.loadJSON>.
+       opt - (object) Animation options. It's an object with optional properties described below
+       type - (string) Default's *nothing*. Type of the animation. Can be "nothing", "replot", "fade:con".
+       duration - Described in <Options.Fx>.
+       fps - Described in <Options.Fx>.
+       transition - Described in <Options.Fx>.
+       hideLabels - (boolean) Default's *true*. Hide labels during the animation.
+       id - (string) The shared <Graph.Node> id between both graphs.
+       
+       extraModes - (optional|object) When morphing with an animation, dollar prefixed data parameters are added to 
+                    *endData* and not *data* itself. This way you can animate dollar prefixed parameters during your morphing operation. 
+                    For animating these extra-parameters you have to specify an object that has animation groups as keys and animation 
+                    properties as values, just like specified in <Graph.Plot.animate>.
+   
+      Example:
+      (start code js)
+        //...json contains a tree or graph structure...
+
+        var viz = new $jit.Viz(options);
+        viz.op.morph(json, {
+          type: 'fade',
+          duration: 1000,
+          hideLabels: false,
+          transition: $jit.Trans.Quart.easeOut
+        });
+        //or also
+        viz.op.morph(json, {
+          type: 'fade',
+          duration: 1500
+        });
+        //if the json data contains dollar prefixed params
+        //like $width or $height these too can be animated
+        viz.op.morph(json, {
+          type: 'fade',
+          duration: 1500
+        }, {
+          'node-property': ['width', 'height']
+        });
+      (end code)
+    
+    */
+    morph: function(json, opt, extraModes) {
+        extraModes = extraModes || {};
+        var viz = this.viz;
+        var options = $.merge(this.options, viz.controller, opt), root = viz.root;
+        var graph;
+        //TODO(nico) this hack makes morphing work with the Hypertree. 
+        //Need to check if it has been solved and this can be removed.
+        viz.root = opt.id || viz.root;
+        switch(options.type) {
+            case 'nothing':
+                graph = viz.construct(json);
+                graph.eachNode(function(elem) {
+                  var nodeExists = viz.graph.hasNode(elem.id);  
+                  elem.eachAdjacency(function(adj) {
+                    var adjExists = !!viz.graph.getAdjacence(adj.nodeFrom.id, adj.nodeTo.id);
+                    viz.graph.addAdjacence(adj.nodeFrom, adj.nodeTo, adj.data);
+                    //Update data properties if the node existed
+                    if(adjExists) {
+                      var addedAdj = viz.graph.getAdjacence(adj.nodeFrom.id, adj.nodeTo.id);
+                      for(var prop in (adj.data || {})) {
+                        addedAdj.data[prop] = adj.data[prop];
+                      }
+                    }
+                  });
+                  //Update data properties if the node existed
+                  if(nodeExists) {
+                    var addedNode = viz.graph.getNode(elem.id);
+                    for(var prop in (elem.data || {})) {
+                      addedNode.data[prop] = elem.data[prop];
+                    }
+                  }
+                });
+                viz.graph.eachNode(function(elem) {
+                    elem.eachAdjacency(function(adj) {
+                        if(!graph.getAdjacence(adj.nodeFrom.id, adj.nodeTo.id)) {
+                            viz.graph.removeAdjacence(adj.nodeFrom.id, adj.nodeTo.id);
+                        }
+                    });
+                    if(!graph.hasNode(elem.id)) viz.graph.removeNode(elem.id);
+                });
+                
+                break;
+            
+            case 'replot':
+                viz.labels.clearLabels(true);
+                this.morph(json, { type: 'nothing' });
+                viz.refresh(true);
+                viz.refresh(true);
+                break;
+                
+            case 'fade:seq': case 'fade': case 'fade:con':
+                that = this;
+                graph = viz.construct(json);
+                //preprocessing for nodes to delete.
+                //get node property modes to interpolate
+                var nodeModes = ('node-property' in extraModes) 
+                  && $.map($.splat(extraModes['node-property']), 
+                      function(n) { return '$' + n; });
+                viz.graph.eachNode(function(elem) {
+                  var graphNode = graph.getNode(elem.id);   
+                  if(!graphNode) {
+                      elem.setData('alpha', 1);
+                      elem.setData('alpha', 1, 'start');
+                      elem.setData('alpha', 0, 'end');
+                      elem.ignore = true;
+                    } else {
+                      //Update node data information
+                      var graphNodeData = graphNode.data;
+                      for(var prop in graphNodeData) {
+                        if(nodeModes && ($.indexOf(nodeModes, prop) > -1)) {
+                          elem.endData[prop] = graphNodeData[prop];
+                        } else {
+                          elem.data[prop] = graphNodeData[prop];
+                        }
+                      }
+                    }
+                }); 
+                viz.graph.eachNode(function(elem) {
+                    if(elem.ignore) return;
+                    elem.eachAdjacency(function(adj) {
+                        if(adj.nodeFrom.ignore || adj.nodeTo.ignore) return;
+                        var nodeFrom = graph.getNode(adj.nodeFrom.id);
+                        var nodeTo = graph.getNode(adj.nodeTo.id);
+                        if(!nodeFrom.adjacentTo(nodeTo)) {
+                            var adj = viz.graph.getAdjacence(nodeFrom.id, nodeTo.id);
+                            fadeEdges = true;
+                            adj.setData('alpha', 1);
+                            adj.setData('alpha', 1, 'start');
+                            adj.setData('alpha', 0, 'end');
+                        }
+                    });
+                }); 
+                //preprocessing for adding nodes.
+                var fadeEdges = this.preprocessSum(graph);
+
+                var modes = !fadeEdges? ['node-property:alpha'] : 
+                                        ['node-property:alpha', 
+                                         'edge-property:alpha'];
+                //Append extra node-property animations (if any)
+                modes[0] = modes[0] + (('node-property' in extraModes)? 
+                    (':' + $.splat(extraModes['node-property']).join(':')) : '');
+                //Append extra edge-property animations (if any)
+                modes[1] = (modes[1] || 'edge-property:alpha') + (('edge-property' in extraModes)? 
+                    (':' + $.splat(extraModes['edge-property']).join(':')) : '');
+                //Add label-property animations (if any)
+                if('label-property' in extraModes) {
+                  modes.push('label-property:' + $.splat(extraModes['label-property']).join(':'))
+                }
+                //only use reposition if its implemented.
+                if (viz.reposition) {
+                  viz.reposition();
+                } else {
+                  viz.compute('end');
+                }
+                viz.graph.eachNode(function(elem) {
+                    if (elem.id != root && elem.pos.getp().equals(Polar.KER)) {
+                      elem.pos.set(elem.endPos); elem.startPos.set(elem.endPos);
+                    }
+                });
+                viz.fx.animate($.merge(options, {
+                    modes: [extraModes.position || 'polar'].concat(modes),
+                    onComplete: function() {
+                        viz.graph.eachNode(function(elem) {
+                            if(elem.ignore) viz.graph.removeNode(elem.id);
+                        });
+                        viz.graph.eachNode(function(elem) {
+                            elem.eachAdjacency(function(adj) {
+                                if(adj.ignore) viz.graph.removeAdjacence(adj.nodeFrom.id, adj.nodeTo.id);
+                            });
+                        });
+                        options.onComplete();
+                    }
+                }));
+                break;
+
+            default:;
+        }
+    },
+
+    
+  /*
+    Method: contract
+ 
+    Collapses the subtree of the given node. The node will have a _collapsed=true_ property.
+    
+    Parameters:
+ 
+    node - (object) A <Graph.Node>.
+    opt - (object) An object containing options described below
+    type - (string) Whether to 'replot' or 'animate' the contraction.
+   
+    There are also a number of Animation options. For more information see <Options.Fx>.
+
+    Example:
+    (start code js)
+     var viz = new $jit.Viz(options);
+     viz.op.contract(node, {
+       type: 'animate',
+       duration: 1000,
+       hideLabels: true,
+       transition: $jit.Trans.Quart.easeOut
+     });
+   (end code)
+ 
+   */
+    contract: function(node, opt) {
+      var viz = this.viz;
+      if(node.collapsed || !node.anySubnode($.lambda(true))) return;
+      opt = $.merge(this.options, viz.config, opt || {}, {
+        'modes': ['node-property:alpha:span', 'linear']
+      });
+      node.collapsed = true;
+      (function subn(n) {
+        n.eachSubnode(function(ch) {
+          ch.ignore = true;
+          ch.setData('alpha', 0, opt.type == 'animate'? 'end' : 'current');
+          subn(ch);
+        });
+      })(node);
+      if(opt.type == 'animate') {
+        viz.compute('end');
+        if(viz.rotated) {
+          viz.rotate(viz.rotated, 'none', {
+            'property':'end'
+          });
+        }
+        (function subn(n) {
+          n.eachSubnode(function(ch) {
+            ch.setPos(node.getPos('end'), 'end');
+            subn(ch);
+          });
+        })(node);
+        viz.fx.animate(opt);
+      } else if(opt.type == 'replot'){
+        viz.refresh();
+      }
+    },
+    
+    /*
+    Method: expand
+ 
+    Expands the previously contracted subtree. The given node must have the _collapsed=true_ property.
+    
+    Parameters:
+ 
+    node - (object) A <Graph.Node>.
+    opt - (object) An object containing options described below
+    type - (string) Whether to 'replot' or 'animate'.
+     
+    There are also a number of Animation options. For more information see <Options.Fx>.
+
+    Example:
+    (start code js)
+      var viz = new $jit.Viz(options);
+      viz.op.expand(node, {
+        type: 'animate',
+        duration: 1000,
+        hideLabels: true,
+        transition: $jit.Trans.Quart.easeOut
+      });
+    (end code)
+ 
+   */
+    expand: function(node, opt) {
+      if(!('collapsed' in node)) return;
+      var viz = this.viz;
+      opt = $.merge(this.options, viz.config, opt || {}, {
+        'modes': ['node-property:alpha:span', 'linear']
+      });
+      delete node.collapsed;
+      (function subn(n) {
+        n.eachSubnode(function(ch) {
+          delete ch.ignore;
+          ch.setData('alpha', 1, opt.type == 'animate'? 'end' : 'current');
+          subn(ch);
+        });
+      })(node);
+      if(opt.type == 'animate') {
+        viz.compute('end');
+        if(viz.rotated) {
+          viz.rotate(viz.rotated, 'none', {
+            'property':'end'
+          });
+        }
+        viz.fx.animate(opt);
+      } else if(opt.type == 'replot'){
+        viz.refresh();
+      }
+    },
+
+    preprocessSum: function(graph) {
+        var viz = this.viz;
+        graph.eachNode(function(elem) {
+            if(!viz.graph.hasNode(elem.id)) {
+                viz.graph.addNode(elem);
+                var n = viz.graph.getNode(elem.id);
+                n.setData('alpha', 0);
+                n.setData('alpha', 0, 'start');
+                n.setData('alpha', 1, 'end');
+            }
+        }); 
+        var fadeEdges = false;
+        graph.eachNode(function(elem) {
+            elem.eachAdjacency(function(adj) {
+                var nodeFrom = viz.graph.getNode(adj.nodeFrom.id);
+                var nodeTo = viz.graph.getNode(adj.nodeTo.id);
+                if(!nodeFrom.adjacentTo(nodeTo)) {
+                    var adj = viz.graph.addAdjacence(nodeFrom, nodeTo, adj.data);
+                    if(nodeFrom.startAlpha == nodeFrom.endAlpha 
+                    && nodeTo.startAlpha == nodeTo.endAlpha) {
+                        fadeEdges = true;
+                        adj.setData('alpha', 0);
+                        adj.setData('alpha', 0, 'start');
+                        adj.setData('alpha', 1, 'end');
+                    } 
+                }
+            });
+        }); 
+        return fadeEdges;
+    }
+};
+
+
+
+/*
+   File: Helpers.js
+ 
+   Helpers are objects that contain rendering primitives (like rectangles, ellipses, etc), for plotting nodes and edges.
+   Helpers also contain implementations of the *contains* method, a method returning a boolean indicating whether the mouse
+   position is over the rendered shape.
+   
+   Helpers are very useful when implementing new NodeTypes, since you can access them through *this.nodeHelper* and 
+   *this.edgeHelper* <Graph.Plot> properties, providing you with simple primitives and mouse-position check functions.
+   
+   Example:
+   (start code js)
+   //implement a new node type
+   $jit.Viz.Plot.NodeTypes.implement({
+     'customNodeType': {
+       'render': function(node, canvas) {
+         this.nodeHelper.circle.render ...
+       },
+       'contains': function(node, pos) {
+         this.nodeHelper.circle.contains ...
+       }
+     }
+   });
+   //implement an edge type
+   $jit.Viz.Plot.EdgeTypes.implement({
+     'customNodeType': {
+       'render': function(node, canvas) {
+         this.edgeHelper.circle.render ...
+       },
+       //optional
+       'contains': function(node, pos) {
+         this.edgeHelper.circle.contains ...
+       }
+     }
+   });
+   (end code)
+
+*/
+
+/*
+   Object: NodeHelper
+   
+   Contains rendering and other type of primitives for simple shapes.
+ */
+var NodeHelper = {
+  'none': {
+    'render': $.empty,
+    'contains': $.lambda(false)
+  },
+  /*
+   Object: NodeHelper.circle
+   */
+  'circle': {
+    /*
+     Method: render
+     
+     Renders a circle into the canvas.
+     
+     Parameters:
+     
+     type - (string) Possible options are 'fill' or 'stroke'.
+     pos - (object) An *x*, *y* object with the position of the center of the circle.
+     radius - (number) The radius of the circle to be rendered.
+     canvas - (object) A <Canvas> instance.
+     
+     Example:
+     (start code js)
+     NodeHelper.circle.render('fill', { x: 10, y: 30 }, 30, viz.canvas);
+     (end code)
+     */
+    'render': function(type, pos, radius, canvas){
+      var ctx = canvas.getCtx();
+      ctx.beginPath();
+      ctx.arc(pos.x, pos.y, radius, 0, Math.PI * 2, true);
+      ctx.closePath();
+      ctx[type]();
+    },
+    /*
+    Method: contains
+    
+    Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+    
+    Parameters:
+    
+    npos - (object) An *x*, *y* object with the <Graph.Node> position.
+    pos - (object) An *x*, *y* object with the position to check.
+    radius - (number) The radius of the rendered circle.
+    
+    Example:
+    (start code js)
+    NodeHelper.circle.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, 30); //true
+    (end code)
+    */
+    'contains': function(npos, pos, radius){
+      var diffx = npos.x - pos.x, 
+          diffy = npos.y - pos.y, 
+          diff = diffx * diffx + diffy * diffy;
+      return diff <= radius * radius;
+    }
+  },
+  /*
+  Object: NodeHelper.ellipse
+  */
+  'ellipse': {
+    /*
+    Method: render
+    
+    Renders an ellipse into the canvas.
+    
+    Parameters:
+    
+    type - (string) Possible options are 'fill' or 'stroke'.
+    pos - (object) An *x*, *y* object with the position of the center of the ellipse.
+    width - (number) The width of the ellipse.
+    height - (number) The height of the ellipse.
+    canvas - (object) A <Canvas> instance.
+    
+    Example:
+    (start code js)
+    NodeHelper.ellipse.render('fill', { x: 10, y: 30 }, 30, 40, viz.canvas);
+    (end code)
+    */
+    'render': function(type, pos, width, height, canvas){
+      var ctx = canvas.getCtx(),
+          scalex = 1,
+          scaley = 1,
+          scaleposx = 1,
+          scaleposy = 1,
+          radius = 0;
+
+      if (width > height) {
+          radius = width / 2;
+          scaley = height / width;
+          scaleposy = width / height;
+      } else {
+          radius = height / 2;
+          scalex = width / height;
+          scaleposx = height / width;
+      }
+
+      ctx.save();
+      ctx.scale(scalex, scaley);
+      ctx.beginPath();
+      ctx.arc(pos.x * scaleposx, pos.y * scaleposy, radius, 0, Math.PI * 2, true);
+      ctx.closePath();
+      ctx[type]();
+      ctx.restore();
+    },
+    /*
+    Method: contains
+    
+    Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+    
+    Parameters:
+    
+    npos - (object) An *x*, *y* object with the <Graph.Node> position.
+    pos - (object) An *x*, *y* object with the position to check.
+    width - (number) The width of the rendered ellipse.
+    height - (number) The height of the rendered ellipse.
+    
+    Example:
+    (start code js)
+    NodeHelper.ellipse.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, 30, 40);
+    (end code)
+    */
+    'contains': function(npos, pos, width, height){
+      var radius = 0,
+          scalex = 1,
+          scaley = 1,
+          diffx = 0,
+          diffy = 0,
+          diff = 0;
+
+      if (width > height) {
+	      radius = width / 2;
+	      scaley = height / width;
+      } else {
+          radius = height / 2;
+          scalex = width / height;
+      }
+
+      diffx = (npos.x - pos.x) * (1 / scalex);
+      diffy = (npos.y - pos.y) * (1 / scaley);
+      diff = diffx * diffx + diffy * diffy;
+      return diff <= radius * radius;
+    }
+  },
+  /*
+  Object: NodeHelper.square
+  */
+  'square': {
+    /*
+    Method: render
+    
+    Renders a square into the canvas.
+    
+    Parameters:
+    
+    type - (string) Possible options are 'fill' or 'stroke'.
+    pos - (object) An *x*, *y* object with the position of the center of the square.
+    dim - (number) The radius (or half-diameter) of the square.
+    canvas - (object) A <Canvas> instance.
+    
+    Example:
+    (start code js)
+    NodeHelper.square.render('stroke', { x: 10, y: 30 }, 40, viz.canvas);
+    (end code)
+    */
+    'render': function(type, pos, dim, canvas){
+      canvas.getCtx()[type + "Rect"](pos.x - dim, pos.y - dim, 2*dim, 2*dim);
+    },
+    /*
+    Method: contains
+    
+    Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+    
+    Parameters:
+    
+    npos - (object) An *x*, *y* object with the <Graph.Node> position.
+    pos - (object) An *x*, *y* object with the position to check.
+    dim - (number) The radius (or half-diameter) of the square.
+    
+    Example:
+    (start code js)
+    NodeHelper.square.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, 30);
+    (end code)
+    */
+    'contains': function(npos, pos, dim){
+      return Math.abs(pos.x - npos.x) <= dim && Math.abs(pos.y - npos.y) <= dim;
+    }
+  },
+  /*
+  Object: NodeHelper.rectangle
+  */
+  'rectangle': {
+    /*
+    Method: render
+    
+    Renders a rectangle into the canvas.
+    
+    Parameters:
+    
+    type - (string) Possible options are 'fill' or 'stroke'.
+    pos - (object) An *x*, *y* object with the position of the center of the rectangle.
+    width - (number) The width of the rectangle.
+    height - (number) The height of the rectangle.
+    canvas - (object) A <Canvas> instance.
+    
+    Example:
+    (start code js)
+    NodeHelper.rectangle.render('fill', { x: 10, y: 30 }, 30, 40, viz.canvas);
+    (end code)
+    */
+    'render': function(type, pos, width, height, canvas){
+      canvas.getCtx()[type + "Rect"](pos.x - width / 2, pos.y - height / 2, 
+                                      width, height);
+    },
+    /*
+    Method: contains
+    
+    Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+    
+    Parameters:
+    
+    npos - (object) An *x*, *y* object with the <Graph.Node> position.
+    pos - (object) An *x*, *y* object with the position to check.
+    width - (number) The width of the rendered rectangle.
+    height - (number) The height of the rendered rectangle.
+    
+    Example:
+    (start code js)
+    NodeHelper.rectangle.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, 30, 40);
+    (end code)
+    */
+    'contains': function(npos, pos, width, height){
+      return Math.abs(pos.x - npos.x) <= width / 2
+          && Math.abs(pos.y - npos.y) <= height / 2;
+    }
+  },
+  /*
+  Object: NodeHelper.triangle
+  */
+  'triangle': {
+    /*
+    Method: render
+    
+    Renders a triangle into the canvas.
+    
+    Parameters:
+    
+    type - (string) Possible options are 'fill' or 'stroke'.
+    pos - (object) An *x*, *y* object with the position of the center of the triangle.
+    dim - (number) Half the base and half the height of the triangle.
+    canvas - (object) A <Canvas> instance.
+    
+    Example:
+    (start code js)
+    NodeHelper.triangle.render('stroke', { x: 10, y: 30 }, 40, viz.canvas);
+    (end code)
+    */
+    'render': function(type, pos, dim, canvas){
+      var ctx = canvas.getCtx(), 
+          c1x = pos.x, 
+          c1y = pos.y - dim, 
+          c2x = c1x - dim, 
+          c2y = pos.y + dim, 
+          c3x = c1x + dim, 
+          c3y = c2y;
+      ctx.beginPath();
+      ctx.moveTo(c1x, c1y);
+      ctx.lineTo(c2x, c2y);
+      ctx.lineTo(c3x, c3y);
+      ctx.closePath();
+      ctx[type]();
+    },
+    /*
+    Method: contains
+    
+    Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+    
+    Parameters:
+    
+    npos - (object) An *x*, *y* object with the <Graph.Node> position.
+    pos - (object) An *x*, *y* object with the position to check.
+    dim - (number) Half the base and half the height of the triangle.
+    
+    Example:
+    (start code js)
+    NodeHelper.triangle.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, 30);
+    (end code)
+    */
+    'contains': function(npos, pos, dim) {
+      return NodeHelper.circle.contains(npos, pos, dim);
+    }
+  },
+  /*
+  Object: NodeHelper.star
+  */
+  'star': {
+    /*
+    Method: render
+    
+    Renders a star (concave decagon) into the canvas.
+    
+    Parameters:
+    
+    type - (string) Possible options are 'fill' or 'stroke'.
+    pos - (object) An *x*, *y* object with the position of the center of the star.
+    dim - (number) The length of a side of a concave decagon.
+    canvas - (object) A <Canvas> instance.
+    
+    Example:
+    (start code js)
+    NodeHelper.star.render('stroke', { x: 10, y: 30 }, 40, viz.canvas);
+    (end code)
+    */
+    'render': function(type, pos, dim, canvas){
+      var ctx = canvas.getCtx(), 
+          pi5 = Math.PI / 5;
+      ctx.save();
+      ctx.translate(pos.x, pos.y);
+      ctx.beginPath();
+      ctx.moveTo(dim, 0);
+      for (var i = 0; i < 9; i++) {
+        ctx.rotate(pi5);
+        if (i % 2 == 0) {
+          ctx.lineTo((dim / 0.525731) * 0.200811, 0);
+        } else {
+          ctx.lineTo(dim, 0);
+        }
+      }
+      ctx.closePath();
+      ctx[type]();
+      ctx.restore();
+    },
+    /*
+    Method: contains
+    
+    Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+    
+    Parameters:
+    
+    npos - (object) An *x*, *y* object with the <Graph.Node> position.
+    pos - (object) An *x*, *y* object with the position to check.
+    dim - (number) The length of a side of a concave decagon.
+    
+    Example:
+    (start code js)
+    NodeHelper.star.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, 30);
+    (end code)
+    */
+    'contains': function(npos, pos, dim) {
+      return NodeHelper.circle.contains(npos, pos, dim);
+    }
+  }
+};
+
+/*
+  Object: EdgeHelper
+  
+  Contains rendering primitives for simple edge shapes.
+*/
+var EdgeHelper = {
+  /*
+    Object: EdgeHelper.line
+  */
+  'line': {
+      /*
+      Method: render
+      
+      Renders a line into the canvas.
+      
+      Parameters:
+      
+      from - (object) An *x*, *y* object with the starting position of the line.
+      to - (object) An *x*, *y* object with the ending position of the line.
+      canvas - (object) A <Canvas> instance.
+      
+      Example:
+      (start code js)
+      EdgeHelper.line.render({ x: 10, y: 30 }, { x: 10, y: 50 }, viz.canvas);
+      (end code)
+      */
+      'render': function(from, to, canvas){
+        var ctx = canvas.getCtx();
+        ctx.beginPath();
+        ctx.moveTo(from.x, from.y);
+        ctx.lineTo(to.x, to.y);
+        ctx.stroke();
+      },
+      /*
+      Method: contains
+      
+      Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+      
+      Parameters:
+      
+      posFrom - (object) An *x*, *y* object with a <Graph.Node> position.
+      posTo - (object) An *x*, *y* object with a <Graph.Node> position.
+      pos - (object) An *x*, *y* object with the position to check.
+      epsilon - (number) The dimension of the shape.
+      
+      Example:
+      (start code js)
+      EdgeHelper.line.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, { x: 15, y: 35 }, 30);
+      (end code)
+      */
+      'contains': function(posFrom, posTo, pos, epsilon) {
+        var min = Math.min, 
+            max = Math.max,
+            minPosX = min(posFrom.x, posTo.x),
+            maxPosX = max(posFrom.x, posTo.x),
+            minPosY = min(posFrom.y, posTo.y),
+            maxPosY = max(posFrom.y, posTo.y);
+        
+        if(pos.x >= minPosX && pos.x <= maxPosX 
+            && pos.y >= minPosY && pos.y <= maxPosY) {
+          if(Math.abs(posTo.x - posFrom.x) <= epsilon) {
+            return true;
+          }
+          var dist = (posTo.y - posFrom.y) / (posTo.x - posFrom.x) * (pos.x - posFrom.x) + posFrom.y;
+          return Math.abs(dist - pos.y) <= epsilon;
+        }
+        return false;
+      }
+    },
+  /*
+    Object: EdgeHelper.arrow
+  */
+  'arrow': {
+      /*
+      Method: render
+      
+      Renders an arrow into the canvas.
+      
+      Parameters:
+      
+      from - (object) An *x*, *y* object with the starting position of the arrow.
+      to - (object) An *x*, *y* object with the ending position of the arrow.
+      dim - (number) The dimension of the arrow.
+      swap - (boolean) Whether to set the arrow pointing to the starting position or the ending position.
+      canvas - (object) A <Canvas> instance.
+      
+      Example:
+      (start code js)
+      EdgeHelper.arrow.render({ x: 10, y: 30 }, { x: 10, y: 50 }, 13, false, viz.canvas);
+      (end code)
+      */
+    'render': function(from, to, dim, swap, canvas){
+        var ctx = canvas.getCtx();
+        // invert edge direction
+        if (swap) {
+          var tmp = from;
+          from = to;
+          to = tmp;
+        }
+        var vect = new Complex(to.x - from.x, to.y - from.y);
+        vect.$scale(dim / vect.norm());
+        var intermediatePoint = new Complex(to.x - vect.x, to.y - vect.y),
+            normal = new Complex(-vect.y / 2, vect.x / 2),
+            v1 = intermediatePoint.add(normal), 
+            v2 = intermediatePoint.$add(normal.$scale(-1));
+        
+        ctx.beginPath();
+        ctx.moveTo(from.x, from.y);
+        ctx.lineTo(to.x, to.y);
+        ctx.stroke();
+        ctx.beginPath();
+        ctx.moveTo(v1.x, v1.y);
+        ctx.lineTo(v2.x, v2.y);
+        ctx.lineTo(to.x, to.y);
+        ctx.closePath();
+        ctx.fill();
+    },
+    /*
+    Method: contains
+    
+    Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+    
+    Parameters:
+    
+    posFrom - (object) An *x*, *y* object with a <Graph.Node> position.
+    posTo - (object) An *x*, *y* object with a <Graph.Node> position.
+    pos - (object) An *x*, *y* object with the position to check.
+    epsilon - (number) The dimension of the shape.
+    
+    Example:
+    (start code js)
+    EdgeHelper.arrow.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, { x: 15, y: 35 }, 30);
+    (end code)
+    */
+    'contains': function(posFrom, posTo, pos, epsilon) {
+      return EdgeHelper.line.contains(posFrom, posTo, pos, epsilon);
+    }
+  },
+  /*
+    Object: EdgeHelper.hyperline
+  */
+  'hyperline': {
+    /*
+    Method: render
+    
+    Renders a hyperline into the canvas. A hyperline are the lines drawn for the <Hypertree> visualization.
+    
+    Parameters:
+    
+    from - (object) An *x*, *y* object with the starting position of the hyperline. *x* and *y* must belong to [0, 1).
+    to - (object) An *x*, *y* object with the ending position of the hyperline. *x* and *y* must belong to [0, 1).
+    r - (number) The scaling factor.
+    canvas - (object) A <Canvas> instance.
+    
+    Example:
+    (start code js)
+    EdgeHelper.hyperline.render({ x: 10, y: 30 }, { x: 10, y: 50 }, 100, viz.canvas);
+    (end code)
+    */
+    'render': function(from, to, r, canvas){
+      var ctx = canvas.getCtx();  
+      var centerOfCircle = computeArcThroughTwoPoints(from, to);
+      if (centerOfCircle.a > 1000 || centerOfCircle.b > 1000
+          || centerOfCircle.ratio < 0) {
+        ctx.beginPath();
+        ctx.moveTo(from.x * r, from.y * r);
+        ctx.lineTo(to.x * r, to.y * r);
+        ctx.stroke();
+      } else {
+        var angleBegin = Math.atan2(to.y - centerOfCircle.y, to.x
+            - centerOfCircle.x);
+        var angleEnd = Math.atan2(from.y - centerOfCircle.y, from.x
+            - centerOfCircle.x);
+        var sense = sense(angleBegin, angleEnd);
+        ctx.beginPath();
+        ctx.arc(centerOfCircle.x * r, centerOfCircle.y * r, centerOfCircle.ratio
+            * r, angleBegin, angleEnd, sense);
+        ctx.stroke();
+      }
+      /*      
+        Calculates the arc parameters through two points.
+        
+        More information in <http://en.wikipedia.org/wiki/Poincar%C3%A9_disc_model#Analytic_geometry_constructions_in_the_hyperbolic_plane> 
+      
+        Parameters:
+      
+        p1 - A <Complex> instance.
+        p2 - A <Complex> instance.
+        scale - The Disk's diameter.
+      
+        Returns:
+      
+        An object containing some arc properties.
+      */
+      function computeArcThroughTwoPoints(p1, p2){
+        var aDen = (p1.x * p2.y - p1.y * p2.x), bDen = aDen;
+        var sq1 = p1.squaredNorm(), sq2 = p2.squaredNorm();
+        // Fall back to a straight line
+        if (aDen == 0)
+          return {
+            x: 0,
+            y: 0,
+            ratio: -1
+          };
+    
+        var a = (p1.y * sq2 - p2.y * sq1 + p1.y - p2.y) / aDen;
+        var b = (p2.x * sq1 - p1.x * sq2 + p2.x - p1.x) / bDen;
+        var x = -a / 2;
+        var y = -b / 2;
+        var squaredRatio = (a * a + b * b) / 4 - 1;
+        // Fall back to a straight line
+        if (squaredRatio < 0)
+          return {
+            x: 0,
+            y: 0,
+            ratio: -1
+          };
+        var ratio = Math.sqrt(squaredRatio);
+        var out = {
+          x: x,
+          y: y,
+          ratio: ratio > 1000? -1 : ratio,
+          a: a,
+          b: b
+        };
+    
+        return out;
+      }
+      /*      
+        Sets angle direction to clockwise (true) or counterclockwise (false). 
+         
+        Parameters: 
+      
+           angleBegin - Starting angle for drawing the arc. 
+           angleEnd - The HyperLine will be drawn from angleBegin to angleEnd. 
+      
+        Returns: 
+      
+           A Boolean instance describing the sense for drawing the HyperLine. 
+      */
+      function sense(angleBegin, angleEnd){
+        return (angleBegin < angleEnd)? ((angleBegin + Math.PI > angleEnd)? false
+            : true) : ((angleEnd + Math.PI > angleBegin)? true : false);
+      }
+    },
+    /*
+    Method: contains
+    
+    Not Implemented
+    
+    Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+    
+    Parameters:
+    
+    posFrom - (object) An *x*, *y* object with a <Graph.Node> position.
+    posTo - (object) An *x*, *y* object with a <Graph.Node> position.
+    pos - (object) An *x*, *y* object with the position to check.
+    epsilon - (number) The dimension of the shape.
+    
+    Example:
+    (start code js)
+    EdgeHelper.hyperline.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, { x: 15, y: 35 }, 30);
+    (end code)
+    */
+    'contains': $.lambda(false)
+  }
+};
+
+
+/*
+ * File: Graph.Plot.js
+ */
+
+/*
+   Object: Graph.Plot
+
+   <Graph> rendering and animation methods.
+   
+   Properties:
+   
+   nodeHelper - <NodeHelper> object.
+   edgeHelper - <EdgeHelper> object.
+*/
+Graph.Plot = {
+    //Default initializer
+    initialize: function(viz, klass){
+      this.viz = viz;
+      this.config = viz.config;
+      this.node = viz.config.Node;
+      this.edge = viz.config.Edge;
+      this.animation = new Animation;
+      this.nodeTypes = new klass.Plot.NodeTypes;
+      this.edgeTypes = new klass.Plot.EdgeTypes;
+      this.labels = viz.labels;
+   },
+
+    //Add helpers
+    nodeHelper: NodeHelper,
+    edgeHelper: EdgeHelper,
+    
+    Interpolator: {
+        //node/edge property parsers
+        'map': {
+          'border': 'color',
+          'color': 'color',
+          'width': 'number',
+          'height': 'number',
+          'dim': 'number',
+          'alpha': 'number',
+          'lineWidth': 'number',
+          'angularWidth':'number',
+          'span':'number',
+          'valueArray':'array-number',
+          'dimArray':'array-number'
+          //'colorArray':'array-color'
+        },
+        
+        //canvas specific parsers
+        'canvas': {
+          'globalAlpha': 'number',
+          'fillStyle': 'color',
+          'strokeStyle': 'color',
+          'lineWidth': 'number',
+          'shadowBlur': 'number',
+          'shadowColor': 'color',
+          'shadowOffsetX': 'number',
+          'shadowOffsetY': 'number',
+          'miterLimit': 'number'
+        },
+  
+        //label parsers
+        'label': {
+          'size': 'number',
+          'color': 'color'
+        },
+  
+        //Number interpolator
+        'compute': function(from, to, delta) {
+          return from + (to - from) * delta;
+        },
+        
+        //Position interpolators
+        'moebius': function(elem, props, delta, vector) {
+          var v = vector.scale(-delta);  
+          if(v.norm() < 1) {
+              var x = v.x, y = v.y;
+              var ans = elem.startPos
+                .getc().moebiusTransformation(v);
+              elem.pos.setc(ans.x, ans.y);
+              v.x = x; v.y = y;
+            }           
+        },
+
+        'linear': function(elem, props, delta) {
+            var from = elem.startPos.getc(true);
+            var to = elem.endPos.getc(true);
+            elem.pos.setc(this.compute(from.x, to.x, delta), 
+                          this.compute(from.y, to.y, delta));
+        },
+
+        'polar': function(elem, props, delta) {
+          var from = elem.startPos.getp(true);
+          var to = elem.endPos.getp();
+          var ans = to.interpolate(from, delta);
+          elem.pos.setp(ans.theta, ans.rho);
+        },
+        
+        //Graph's Node/Edge interpolators
+        'number': function(elem, prop, delta, getter, setter) {
+          var from = elem[getter](prop, 'start');
+          var to = elem[getter](prop, 'end');
+          elem[setter](prop, this.compute(from, to, delta));
+        },
+
+        'color': function(elem, prop, delta, getter, setter) {
+          var from = $.hexToRgb(elem[getter](prop, 'start'));
+          var to = $.hexToRgb(elem[getter](prop, 'end'));
+          var comp = this.compute;
+          var val = $.rgbToHex([parseInt(comp(from[0], to[0], delta)),
+                                parseInt(comp(from[1], to[1], delta)),
+                                parseInt(comp(from[2], to[2], delta))]);
+          
+          elem[setter](prop, val);
+        },
+        
+        'array-number': function(elem, prop, delta, getter, setter) {
+          var from = elem[getter](prop, 'start'),
+              to = elem[getter](prop, 'end'),
+              cur = [];
+          for(var i=0, l=from.length; i<l; i++) {
+            var fromi = from[i], toi = to[i];
+            if(fromi.length) {
+              for(var j=0, len=fromi.length, curi=[]; j<len; j++) {
+                curi.push(this.compute(fromi[j], toi[j], delta));
+              }
+              cur.push(curi);
+            } else {
+              cur.push(this.compute(fromi, toi, delta));
+            }
+          }
+          elem[setter](prop, cur);
+        },
+        
+        'node': function(elem, props, delta, map, getter, setter) {
+          map = this[map];
+          if(props) {
+            var len = props.length;
+            for(var i=0; i<len; i++) {
+              var pi = props[i];
+              this[map[pi]](elem, pi, delta, getter, setter);
+            }
+          } else {
+            for(var pi in map) {
+              this[map[pi]](elem, pi, delta, getter, setter);
+            }
+          }
+        },
+        
+        'edge': function(elem, props, delta, mapKey, getter, setter) {
+            var adjs = elem.adjacencies;
+            for(var id in adjs) this['node'](adjs[id], props, delta, mapKey, getter, setter);
+        },
+        
+        'node-property': function(elem, props, delta) {
+          this['node'](elem, props, delta, 'map', 'getData', 'setData');
+        },
+        
+        'edge-property': function(elem, props, delta) {
+          this['edge'](elem, props, delta, 'map', 'getData', 'setData');  
+        },
+
+        'label-property': function(elem, props, delta) {
+          this['node'](elem, props, delta, 'label', 'getLabelData', 'setLabelData');
+        },
+        
+        'node-style': function(elem, props, delta) {
+          this['node'](elem, props, delta, 'canvas', 'getCanvasStyle', 'setCanvasStyle');
+        },
+        
+        'edge-style': function(elem, props, delta) {
+          this['edge'](elem, props, delta, 'canvas', 'getCanvasStyle', 'setCanvasStyle');  
+        }
+    },
+    
+  
+    /*
+       sequence
+    
+       Iteratively performs an action while refreshing the state of the visualization.
+
+       Parameters:
+
+       options - (object) An object containing some sequence options described below
+       condition - (function) A function returning a boolean instance in order to stop iterations.
+       step - (function) A function to execute on each step of the iteration.
+       onComplete - (function) A function to execute when the sequence finishes.
+       duration - (number) Duration (in milliseconds) of each step.
+
+      Example:
+       (start code js)
+        var rg = new $jit.RGraph(options);
+        var i = 0;
+        rg.fx.sequence({
+          condition: function() {
+           return i == 10;
+          },
+          step: function() {
+            alert(i++);
+          },
+          onComplete: function() {
+           alert('done!');
+          }
+        });
+       (end code)
+
+    */
+    sequence: function(options) {
+        var that = this;
+        options = $.merge({
+          condition: $.lambda(false),
+          step: $.empty,
+          onComplete: $.empty,
+          duration: 200
+        }, options || {});
+
+        var interval = setInterval(function() {
+          if(options.condition()) {
+            options.step();
+          } else {
+            clearInterval(interval);
+            options.onComplete();
+          }
+          that.viz.refresh(true);
+        }, options.duration);
+    },
+    
+    /*
+      prepare
+ 
+      Prepare graph position and other attribute values before performing an Animation. 
+      This method is used internally by the Toolkit.
+      
+      See also:
+       
+       <Animation>, <Graph.Plot.animate>
+
+    */
+    prepare: function(modes) {
+      var graph = this.viz.graph,
+          accessors = {
+            'node-property': {
+              'getter': 'getData',
+              'setter': 'setData'
+            },
+            'edge-property': {
+              'getter': 'getData',
+              'setter': 'setData'
+            },
+            'node-style': {
+              'getter': 'getCanvasStyle',
+              'setter': 'setCanvasStyle'
+            },
+            'edge-style': {
+              'getter': 'getCanvasStyle',
+              'setter': 'setCanvasStyle'
+            }
+          };
+
+      //parse modes
+      var m = {};
+      if($.type(modes) == 'array') {
+        for(var i=0, len=modes.length; i < len; i++) {
+          var elems = modes[i].split(':');
+          m[elems.shift()] = elems;
+        }
+      } else {
+        for(var p in modes) {
+          if(p == 'position') {
+            m[modes.position] = [];
+          } else {
+            m[p] = $.splat(modes[p]);
+          }
+        }
+      }
+      
+      graph.eachNode(function(node) { 
+        node.startPos.set(node.pos);
+        $.each(['node-property', 'node-style'], function(p) {
+          if(p in m) {
+            var prop = m[p];
+            for(var i=0, l=prop.length; i < l; i++) {
+              node[accessors[p].setter](prop[i], node[accessors[p].getter](prop[i]), 'start');
+            }
+          }
+        });
+        $.each(['edge-property', 'edge-style'], function(p) {
+          if(p in m) {
+            var prop = m[p];
+            node.eachAdjacency(function(adj) {
+              for(var i=0, l=prop.length; i < l; i++) {
+                adj[accessors[p].setter](prop[i], adj[accessors[p].getter](prop[i]), 'start');
+              }
+            });
+          }
+        });
+      });
+      return m;
+    },
+    
+    /*
+       Method: animate
+    
+       Animates a <Graph> by interpolating some <Graph.Node>, <Graph.Adjacence> or <Graph.Label> properties.
+
+       Parameters:
+
+       opt - (object) Animation options. The object properties are described below
+       duration - (optional) Described in <Options.Fx>.
+       fps - (optional) Described in <Options.Fx>.
+       hideLabels - (optional|boolean) Whether to hide labels during the animation.
+       modes - (required|object) An object with animation modes (described below).
+
+       Animation modes:
+       
+       Animation modes are strings representing different node/edge and graph properties that you'd like to animate. 
+       They are represented by an object that has as keys main categories of properties to animate and as values a list 
+       of these specific properties. The properties are described below
+       
+       position - Describes the way nodes' positions must be interpolated. Possible values are 'linear', 'polar' or 'moebius'.
+       node-property - Describes which Node properties will be interpolated. These properties can be any of the ones defined in <Options.Node>.
+       edge-property - Describes which Edge properties will be interpolated. These properties can be any the ones defined in <Options.Edge>.
+       label-property - Describes which Label properties will be interpolated. These properties can be any of the ones defined in <Options.Label> like color or size.
+       node-style - Describes which Node Canvas Styles will be interpolated. These are specific canvas properties like fillStyle, strokeStyle, lineWidth, shadowBlur, shadowColor, shadowOffsetX, shadowOffsetY, etc.
+       edge-style - Describes which Edge Canvas Styles will be interpolated. These are specific canvas properties like fillStyle, strokeStyle, lineWidth, shadowBlur, shadowColor, shadowOffsetX, shadowOffsetY, etc.
+
+       Example:
+       (start code js)
+       var viz = new $jit.Viz(options);
+       //...tweak some Data, CanvasStyles or LabelData properties...
+       viz.fx.animate({
+         modes: {
+           'position': 'linear',
+           'node-property': ['width', 'height'],
+           'node-style': 'shadowColor',
+           'label-property': 'size'
+         },
+         hideLabels: false
+       });
+       //...can also be written like this...
+       viz.fx.animate({
+         modes: ['linear',
+                 'node-property:width:height',
+                 'node-style:shadowColor',
+                 'label-property:size'],
+         hideLabels: false
+       });
+       (end code)
+    */
+    animate: function(opt, versor) {
+      opt = $.merge(this.viz.config, opt || {});
+      var that = this,
+          viz = this.viz,
+          graph  = viz.graph,
+          interp = this.Interpolator,
+          animation =  opt.type === 'nodefx'? this.nodeFxAnimation : this.animation;
+      //prepare graph values
+      var m = this.prepare(opt.modes);
+      
+      //animate
+      if(opt.hideLabels) this.labels.hideLabels(true);
+      animation.setOptions($.extend(opt, {
+        $animating: false,
+        compute: function(delta) {
+          graph.eachNode(function(node) { 
+            for(var p in m) {
+              interp[p](node, m[p], delta, versor);
+            }
+          });
+          that.plot(opt, this.$animating, delta);
+          this.$animating = true;
+        },
+        complete: function() {
+          if(opt.hideLabels) that.labels.hideLabels(false);
+          that.plot(opt);
+          opt.onComplete();
+          //TODO(nico): This shouldn't be here!
+          //opt.onAfterCompute();
+        }       
+      })).start();
+    },
+    
+    /*
+      nodeFx
+   
+      Apply animation to node properties like color, width, height, dim, etc.
+  
+      Parameters:
+  
+      options - Animation options. This object properties is described below
+      elements - The Elements to be transformed. This is an object that has a properties
+      
+      (start code js)
+      'elements': {
+        //can also be an array of ids
+        'id': 'id-of-node-to-transform',
+        //properties to be modified. All properties are optional.
+        'properties': {
+          'color': '#ccc', //some color
+          'width': 10, //some width
+          'height': 10, //some height
+          'dim': 20, //some dim
+          'lineWidth': 10 //some line width
+        } 
+      }
+      (end code)
+      
+      - _reposition_ Whether to recalculate positions and add a motion animation. 
+      This might be used when changing _width_ or _height_ properties in a <Layouts.Tree> like layout. Default's *false*.
+      
+      - _onComplete_ A method that is called when the animation completes.
+      
+      ...and all other <Graph.Plot.animate> options like _duration_, _fps_, _transition_, etc.
+  
+      Example:
+      (start code js)
+       var rg = new RGraph(canvas, config); //can be also Hypertree or ST
+       rg.fx.nodeFx({
+         'elements': {
+           'id':'mynodeid',
+           'properties': {
+             'color':'#ccf'
+           },
+           'transition': Trans.Quart.easeOut
+         }
+       });
+      (end code)    
+   */
+   nodeFx: function(opt) {
+     var viz = this.viz,
+         graph  = viz.graph,
+         animation = this.nodeFxAnimation,
+         options = $.merge(this.viz.config, {
+           'elements': {
+             'id': false,
+             'properties': {}
+           },
+           'reposition': false
+         });
+     opt = $.merge(options, opt || {}, {
+       onBeforeCompute: $.empty,
+       onAfterCompute: $.empty
+     });
+     //check if an animation is running
+     animation.stopTimer();
+     var props = opt.elements.properties;
+     //set end values for nodes
+     if(!opt.elements.id) {
+       graph.eachNode(function(n) {
+         for(var prop in props) {
+           n.setData(prop, props[prop], 'end');
+         }
+       });
+     } else {
+       var ids = $.splat(opt.elements.id);
+       $.each(ids, function(id) {
+         var n = graph.getNode(id);
+         if(n) {
+           for(var prop in props) {
+             n.setData(prop, props[prop], 'end');
+           }
+         }
+       });
+     }
+     //get keys
+     var propnames = [];
+     for(var prop in props) propnames.push(prop);
+     //add node properties modes
+     var modes = ['node-property:' + propnames.join(':')];
+     //set new node positions
+     if(opt.reposition) {
+       modes.push('linear');
+       viz.compute('end');
+     }
+     //animate
+     this.animate($.merge(opt, {
+       modes: modes,
+       type: 'nodefx'
+     }));
+   },
+
+    
+    /*
+       Method: plot
+    
+       Plots a <Graph>.
+
+       Parameters:
+
+       opt - (optional) Plotting options. Most of them are described in <Options.Fx>.
+
+       Example:
+
+       (start code js)
+       var viz = new $jit.Viz(options);
+       viz.fx.plot(); 
+       (end code)
+
+    */
+   plot: function(opt, animating) {
+     var viz = this.viz, 
+         aGraph = viz.graph, 
+         canvas = viz.canvas, 
+         id = viz.root, 
+         that = this, 
+         ctx = canvas.getCtx(), 
+         min = Math.min,
+         opt = opt || this.viz.controller;
+     
+     opt.clearCanvas && canvas.clear();
+       
+     var root = aGraph.getNode(id);
+     if(!root) return;
+     
+     var T = !!root.visited;
+     aGraph.eachNode(function(node) {
+       var nodeAlpha = node.getData('alpha');
+       node.eachAdjacency(function(adj) {
+         var nodeTo = adj.nodeTo;
+         if(!!nodeTo.visited === T && node.drawn && nodeTo.drawn) {
+           !animating && opt.onBeforePlotLine(adj);
+           that.plotLine(adj, canvas, animating);
+           !animating && opt.onAfterPlotLine(adj);
+         }
+       });
+       if(node.drawn) {
+         !animating && opt.onBeforePlotNode(node);
+         that.plotNode(node, canvas, animating);
+         !animating && opt.onAfterPlotNode(node);
+       }
+       if(!that.labelsHidden && opt.withLabels) {
+         if(node.drawn && nodeAlpha >= 0.95) {
+           that.labels.plotLabel(canvas, node, opt);
+         } else {
+           that.labels.hideLabel(node, false);
+         }
+       }
+       node.visited = !T;
+     });
+    },
+
+  /*
+      Plots a Subtree.
+   */
+   plotTree: function(node, opt, animating) {
+       var that = this, 
+       viz = this.viz, 
+       canvas = viz.canvas,
+       config = this.config,
+       ctx = canvas.getCtx();
+       var nodeAlpha = node.getData('alpha');
+       node.eachSubnode(function(elem) {
+         if(opt.plotSubtree(node, elem) && elem.exist && elem.drawn) {
+             var adj = node.getAdjacency(elem.id);
+             !animating && opt.onBeforePlotLine(adj);
+             that.plotLine(adj, canvas, animating);
+             !animating && opt.onAfterPlotLine(adj);
+             that.plotTree(elem, opt, animating);
+         }
+       });
+       if(node.drawn) {
+           !animating && opt.onBeforePlotNode(node);
+           this.plotNode(node, canvas, animating);
+           !animating && opt.onAfterPlotNode(node);
+           if(!opt.hideLabels && opt.withLabels && nodeAlpha >= 0.95) 
+               this.labels.plotLabel(canvas, node, opt);
+           else 
+               this.labels.hideLabel(node, false);
+       } else {
+           this.labels.hideLabel(node, true);
+       }
+   },
+
+  /*
+       Method: plotNode
+    
+       Plots a <Graph.Node>.
+
+       Parameters:
+       
+       node - (object) A <Graph.Node>.
+       canvas - (object) A <Canvas> element.
+
+    */
+    plotNode: function(node, canvas, animating) {
+        var f = node.getData('type'), 
+            ctxObj = this.node.CanvasStyles;
+        if(f != 'none') {
+          var width = node.getData('lineWidth'),
+              color = node.getData('color'),
+              alpha = node.getData('alpha'),
+              ctx = canvas.getCtx();
+          ctx.save();
+          ctx.lineWidth = width;
+          ctx.fillStyle = ctx.strokeStyle = color;
+          ctx.globalAlpha = alpha;
+          
+          for(var s in ctxObj) {
+            ctx[s] = node.getCanvasStyle(s);
+          }
+
+          this.nodeTypes[f].render.call(this, node, canvas, animating);
+          ctx.restore();
+        }
+    },
+    
+    /*
+       Method: plotLine
+    
+       Plots a <Graph.Adjacence>.
+
+       Parameters:
+
+       adj - (object) A <Graph.Adjacence>.
+       canvas - (object) A <Canvas> instance.
+
+    */
+    plotLine: function(adj, canvas, animating) {
+      var f = adj.getData('type'),
+          ctxObj = this.edge.CanvasStyles;
+      if(f != 'none') {
+        var width = adj.getData('lineWidth'),
+            color = adj.getData('color'),
+            ctx = canvas.getCtx(),
+            nodeFrom = adj.nodeFrom,
+            nodeTo = adj.nodeTo;
+        
+        ctx.save();
+        ctx.lineWidth = width;
+        ctx.fillStyle = ctx.strokeStyle = color;
+        ctx.globalAlpha = Math.min(nodeFrom.getData('alpha'), 
+            nodeTo.getData('alpha'), 
+            adj.getData('alpha'));
+        
+        for(var s in ctxObj) {
+          ctx[s] = adj.getCanvasStyle(s);
+        }
+
+        this.edgeTypes[f].render.call(this, adj, canvas, animating);
+        ctx.restore();
+      }
+    }    
+  
+};
+
+/*
+  Object: Graph.Plot3D
+  
+  <Graph> 3D rendering and animation methods.
+  
+  Properties:
+  
+  nodeHelper - <NodeHelper> object.
+  edgeHelper - <EdgeHelper> object.
+
+*/
+Graph.Plot3D = $.merge(Graph.Plot, {
+  Interpolator: {
+    'linear': function(elem, props, delta) {
+      var from = elem.startPos.getc(true);
+      var to = elem.endPos.getc(true);
+      elem.pos.setc(this.compute(from.x, to.x, delta), 
+                    this.compute(from.y, to.y, delta),
+                    this.compute(from.z, to.z, delta));
+    }
+  },
+  
+  plotNode: function(node, canvas) {
+    if(node.getData('type') == 'none') return;
+    this.plotElement(node, canvas, {
+      getAlpha: function() {
+        return node.getData('alpha');
+      }
+    });
+  },
+  
+  plotLine: function(adj, canvas) {
+    if(adj.getData('type') == 'none') return;
+    this.plotElement(adj, canvas, {
+      getAlpha: function() {
+        return Math.min(adj.nodeFrom.getData('alpha'),
+                        adj.nodeTo.getData('alpha'),
+                        adj.getData('alpha'));
+      }
+    });
+  },
+  
+  plotElement: function(elem, canvas, opt) {
+    var gl = canvas.getCtx(),
+        viewMatrix = new Matrix4,
+        lighting = canvas.config.Scene.Lighting,
+        wcanvas = canvas.canvases[0],
+        program = wcanvas.program,
+        camera = wcanvas.camera;
+    
+    if(!elem.geometry) {
+      elem.geometry = new O3D[elem.getData('type')];
+    }
+    elem.geometry.update(elem);
+    if(!elem.webGLVertexBuffer) {
+      var vertices = [],
+          faces = [],
+          normals = [],
+          vertexIndex = 0,
+          geom = elem.geometry;
+      
+      for(var i=0, vs=geom.vertices, fs=geom.faces, fsl=fs.length; i<fsl; i++) {
+        var face = fs[i],
+            v1 = vs[face.a],
+            v2 = vs[face.b],
+            v3 = vs[face.c],
+            v4 = face.d? vs[face.d] : false,
+            n = face.normal;
+        
+        vertices.push(v1.x, v1.y, v1.z);
+        vertices.push(v2.x, v2.y, v2.z);
+        vertices.push(v3.x, v3.y, v3.z);
+        if(v4) vertices.push(v4.x, v4.y, v4.z);
+            
+        normals.push(n.x, n.y, n.z);
+        normals.push(n.x, n.y, n.z);
+        normals.push(n.x, n.y, n.z);
+        if(v4) normals.push(n.x, n.y, n.z);
+            
+        faces.push(vertexIndex, vertexIndex +1, vertexIndex +2);
+        if(v4) {
+          faces.push(vertexIndex, vertexIndex +2, vertexIndex +3);
+          vertexIndex += 4;
+        } else {
+          vertexIndex += 3;
+        }
+      }
+      //create and store vertex data
+      elem.webGLVertexBuffer = gl.createBuffer();
+      gl.bindBuffer(gl.ARRAY_BUFFER, elem.webGLVertexBuffer);
+      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
+      //create and store faces index data
+      elem.webGLFaceBuffer = gl.createBuffer();
+      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elem.webGLFaceBuffer);
+      gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(faces), gl.STATIC_DRAW);
+      elem.webGLFaceCount = faces.length;
+      //calculate vertex normals and store them
+      elem.webGLNormalBuffer = gl.createBuffer();
+      gl.bindBuffer(gl.ARRAY_BUFFER, elem.webGLNormalBuffer);
+      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
+    }
+    viewMatrix.multiply(camera.matrix, elem.geometry.matrix);
+    //send matrix data
+    gl.uniformMatrix4fv(program.viewMatrix, false, viewMatrix.flatten());
+    gl.uniformMatrix4fv(program.projectionMatrix, false, camera.projectionMatrix.flatten());
+    //send normal matrix for lighting
+    var normalMatrix = Matrix4.makeInvert(viewMatrix);
+    normalMatrix.$transpose();
+    gl.uniformMatrix4fv(program.normalMatrix, false, normalMatrix.flatten());
+    //send color data
+    var color = $.hexToRgb(elem.getData('color'));
+    color.push(opt.getAlpha());
+    gl.uniform4f(program.color, color[0] / 255, color[1] / 255, color[2] / 255, color[3]);
+    //send lighting data
+    gl.uniform1i(program.enableLighting, lighting.enable);
+    if(lighting.enable) {
+      //set ambient light color
+      if(lighting.ambient) {
+        var acolor = lighting.ambient;
+        gl.uniform3f(program.ambientColor, acolor[0], acolor[1], acolor[2]);
+      }
+      //set directional light
+      if(lighting.directional) {
+        var dir = lighting.directional,
+            color = dir.color,
+            pos = dir.direction,
+            vd = new Vector3(pos.x, pos.y, pos.z).normalize().$scale(-1);
+        gl.uniform3f(program.lightingDirection, vd.x, vd.y, vd.z);
+        gl.uniform3f(program.directionalColor, color[0], color[1], color[2]);
+      }
+    }
+    //send vertices data
+    gl.bindBuffer(gl.ARRAY_BUFFER, elem.webGLVertexBuffer);
+    gl.vertexAttribPointer(program.position, 3, gl.FLOAT, false, 0, 0);
+    //send normals data
+    gl.bindBuffer(gl.ARRAY_BUFFER, elem.webGLNormalBuffer);
+    gl.vertexAttribPointer(program.normal, 3, gl.FLOAT, false, 0, 0);
+    //draw!
+    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elem.webGLFaceBuffer );
+    gl.drawElements(gl.TRIANGLES, elem.webGLFaceCount, gl.UNSIGNED_SHORT, 0);
+  }
+});
+
+
+/*
+ * File: Graph.Label.js
+ *
+*/
+
+/*
+   Object: Graph.Label
+
+   An interface for plotting/hiding/showing labels.
+
+   Description:
+
+   This is a generic interface for plotting/hiding/showing labels.
+   The <Graph.Label> interface is implemented in multiple ways to provide
+   different label types.
+
+   For example, the Graph.Label interface is implemented as <Graph.Label.HTML> to provide
+   HTML label elements. Also we provide the <Graph.Label.SVG> interface for SVG type labels. 
+   The <Graph.Label.Native> interface implements these methods with the native Canvas text rendering functions.
+   
+   All subclasses (<Graph.Label.HTML>, <Graph.Label.SVG> and <Graph.Label.Native>) implement the method plotLabel.
+*/
+
+Graph.Label = {};
+
+/*
+   Class: Graph.Label.Native
+
+   Implements labels natively, using the Canvas text API.
+*/
+Graph.Label.Native = new Class({
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+
+    /*
+       Method: plotLabel
+
+       Plots a label for a given node.
+
+       Parameters:
+
+       canvas - (object) A <Canvas> instance.
+       node - (object) A <Graph.Node>.
+       controller - (object) A configuration object.
+       
+       Example:
+       
+       (start code js)
+       var viz = new $jit.Viz(options);
+       var node = viz.graph.getNode('nodeId');
+       viz.labels.plotLabel(viz.canvas, node, viz.config);
+       (end code)
+    */
+    plotLabel: function(canvas, node, controller) {
+      var ctx = canvas.getCtx();
+      var pos = node.pos.getc(true);
+
+      ctx.font = node.getLabelData('style') + ' ' + node.getLabelData('size') + 'px ' + node.getLabelData('family');
+      ctx.textAlign = node.getLabelData('textAlign');
+      ctx.fillStyle = ctx.strokeStyle = node.getLabelData('color');
+      ctx.textBaseline = node.getLabelData('textBaseline');
+
+      this.renderLabel(canvas, node, controller);
+    },
+
+    /*
+       renderLabel
+
+       Does the actual rendering of the label in the canvas. The default
+       implementation renders the label close to the position of the node, this
+       method should be overriden to position the labels differently.
+
+       Parameters:
+
+       canvas - A <Canvas> instance.
+       node - A <Graph.Node>.
+       controller - A configuration object. See also <Hypertree>, <RGraph>, <ST>.
+    */
+    renderLabel: function(canvas, node, controller) {
+      var ctx = canvas.getCtx();
+      var pos = node.pos.getc(true);
+      ctx.fillText(node.name, pos.x, pos.y + node.getData("height") / 2);
+    },
+
+    hideLabel: $.empty,
+    hideLabels: $.empty
+});
+
+/*
+   Class: Graph.Label.DOM
+
+   Abstract Class implementing some DOM label methods.
+
+   Implemented by:
+
+   <Graph.Label.HTML> and <Graph.Label.SVG>.
+
+*/
+Graph.Label.DOM = new Class({
+    //A flag value indicating if node labels are being displayed or not.
+    labelsHidden: false,
+    //Label container
+    labelContainer: false,
+    //Label elements hash.
+    labels: {},
+
+    /*
+       Method: getLabelContainer
+
+       Lazy fetcher for the label container.
+
+       Returns:
+
+       The label container DOM element.
+
+       Example:
+
+      (start code js)
+        var viz = new $jit.Viz(options);
+        var labelContainer = viz.labels.getLabelContainer();
+        alert(labelContainer.innerHTML);
+      (end code)
+    */
+    getLabelContainer: function() {
+      return this.labelContainer ?
+        this.labelContainer :
+        this.labelContainer = document.getElementById(this.viz.config.labelContainer);
+    },
+
+    /*
+       Method: getLabel
+
+       Lazy fetcher for the label element.
+
+       Parameters:
+
+       id - (string) The label id (which is also a <Graph.Node> id).
+
+       Returns:
+
+       The label element.
+
+       Example:
+
+      (start code js)
+        var viz = new $jit.Viz(options);
+        var label = viz.labels.getLabel('someid');
+        alert(label.innerHTML);
+      (end code)
+
+    */
+    getLabel: function(id) {
+      return (id in this.labels && this.labels[id] != null) ?
+        this.labels[id] :
+        this.labels[id] = document.getElementById(id);
+    },
+
+    /*
+       Method: hideLabels
+
+       Hides all labels (by hiding the label container).
+
+       Parameters:
+
+       hide - (boolean) A boolean value indicating if the label container must be hidden or not.
+
+       Example:
+       (start code js)
+        var viz = new $jit.Viz(options);
+        rg.labels.hideLabels(true);
+       (end code)
+
+    */
+    hideLabels: function (hide) {
+      var container = this.getLabelContainer();
+      if(hide)
+        container.style.display = 'none';
+      else
+        container.style.display = '';
+      this.labelsHidden = hide;
+    },
+
+    /*
+       Method: clearLabels
+
+       Clears the label container.
+
+       Useful when using a new visualization with the same canvas element/widget.
+
+       Parameters:
+
+       force - (boolean) Forces deletion of all labels.
+
+       Example:
+       (start code js)
+        var viz = new $jit.Viz(options);
+        viz.labels.clearLabels();
+        (end code)
+    */
+    clearLabels: function(force) {
+      for(var id in this.labels) {
+        if (force || !this.viz.graph.hasNode(id)) {
+          this.disposeLabel(id);
+          delete this.labels[id];
+        }
+      }
+    },
+
+    /*
+       Method: disposeLabel
+
+       Removes a label.
+
+       Parameters:
+
+       id - (string) A label id (which generally is also a <Graph.Node> id).
+
+       Example:
+       (start code js)
+        var viz = new $jit.Viz(options);
+        viz.labels.disposeLabel('labelid');
+       (end code)
+    */
+    disposeLabel: function(id) {
+      var elem = this.getLabel(id);
+      if(elem && elem.parentNode) {
+        elem.parentNode.removeChild(elem);
+      }
+    },
+
+    /*
+       Method: hideLabel
+
+       Hides the corresponding <Graph.Node> label.
+
+       Parameters:
+
+       node - (object) A <Graph.Node>. Can also be an array of <Graph.Nodes>.
+       show - (boolean) If *true*, nodes will be shown. Otherwise nodes will be hidden.
+
+       Example:
+       (start code js)
+        var rg = new $jit.Viz(options);
+        viz.labels.hideLabel(viz.graph.getNode('someid'), false);
+       (end code)
+    */
+    hideLabel: function(node, show) {
+      node = $.splat(node);
+      var st = show ? "" : "none", lab, that = this;
+      $.each(node, function(n) {
+        var lab = that.getLabel(n.id);
+        if (lab) {
+          lab.style.display = st;
+        }
+      });
+    },
+
+    /*
+       fitsInCanvas
+
+       Returns _true_ or _false_ if the label for the node is contained in the canvas dom element or not.
+
+       Parameters:
+
+       pos - A <Complex> instance (I'm doing duck typing here so any object with _x_ and _y_ parameters will do).
+       canvas - A <Canvas> instance.
+
+       Returns:
+
+       A boolean value specifying if the label is contained in the <Canvas> DOM element or not.
+
+    */
+    fitsInCanvas: function(pos, canvas) {
+      var size = canvas.getSize();
+      if(pos.x >= size.width || pos.x < 0
+         || pos.y >= size.height || pos.y < 0) return false;
+       return true;
+    }
+});
+
+/*
+   Class: Graph.Label.HTML
+
+   Implements HTML labels.
+
+   Extends:
+
+   All <Graph.Label.DOM> methods.
+
+*/
+Graph.Label.HTML = new Class({
+    Implements: Graph.Label.DOM,
+
+    /*
+       Method: plotLabel
+
+       Plots a label for a given node.
+
+       Parameters:
+
+       canvas - (object) A <Canvas> instance.
+       node - (object) A <Graph.Node>.
+       controller - (object) A configuration object.
+       
+      Example:
+       
+       (start code js)
+       var viz = new $jit.Viz(options);
+       var node = viz.graph.getNode('nodeId');
+       viz.labels.plotLabel(viz.canvas, node, viz.config);
+       (end code)
+
+
+    */
+    plotLabel: function(canvas, node, controller) {
+      var id = node.id, tag = this.getLabel(id);
+
+      if(!tag && !(tag = document.getElementById(id))) {
+        tag = document.createElement('div');
+        var container = this.getLabelContainer();
+        tag.id = id;
+        tag.className = 'node';
+        tag.style.position = 'absolute';
+        controller.onCreateLabel(tag, node);
+        container.appendChild(tag);
+        this.labels[node.id] = tag;
+      }
+
+      this.placeLabel(tag, node, controller);
+    }
+});
+
+/*
+   Class: Graph.Label.SVG
+
+   Implements SVG labels.
+
+   Extends:
+
+   All <Graph.Label.DOM> methods.
+*/
+Graph.Label.SVG = new Class({
+    Implements: Graph.Label.DOM,
+
+    /*
+       Method: plotLabel
+
+       Plots a label for a given node.
+
+       Parameters:
+
+       canvas - (object) A <Canvas> instance.
+       node - (object) A <Graph.Node>.
+       controller - (object) A configuration object.
+       
+       Example:
+       
+       (start code js)
+       var viz = new $jit.Viz(options);
+       var node = viz.graph.getNode('nodeId');
+       viz.labels.plotLabel(viz.canvas, node, viz.config);
+       (end code)
+
+
+    */
+    plotLabel: function(canvas, node, controller) {
+      var id = node.id, tag = this.getLabel(id);
+      if(!tag && !(tag = document.getElementById(id))) {
+        var ns = 'http://www.w3.org/2000/svg';
+          tag = document.createElementNS(ns, 'svg:text');
+        var tspan = document.createElementNS(ns, 'svg:tspan');
+        tag.appendChild(tspan);
+        var container = this.getLabelContainer();
+        tag.setAttribute('id', id);
+        tag.setAttribute('class', 'node');
+        container.appendChild(tag);
+        controller.onCreateLabel(tag, node);
+        this.labels[node.id] = tag;
+      }
+      this.placeLabel(tag, node, controller);
+    }
+});
+
+
+
+Graph.Geom = new Class({
+
+  initialize: function(viz) {
+    this.viz = viz;
+    this.config = viz.config;
+    this.node = viz.config.Node;
+    this.edge = viz.config.Edge;
+  },
+  /*
+    Applies a translation to the tree.
+  
+    Parameters:
+  
+    pos - A <Complex> number specifying translation vector.
+    prop - A <Graph.Node> position property ('pos', 'start' or 'end').
+  
+    Example:
+  
+    (start code js)
+      st.geom.translate(new Complex(300, 100), 'end');
+    (end code)
+  */  
+  translate: function(pos, prop) {
+     prop = $.splat(prop);
+     this.viz.graph.eachNode(function(elem) {
+         $.each(prop, function(p) { elem.getPos(p).$add(pos); });
+     });
+  },
+  /*
+    Hides levels of the tree until it properly fits in canvas.
+  */  
+  setRightLevelToShow: function(node, canvas, callback) {
+     var level = this.getRightLevelToShow(node, canvas), 
+         fx = this.viz.labels,
+         opt = $.merge({
+           execShow:true,
+           execHide:true,
+           onHide: $.empty,
+           onShow: $.empty
+         }, callback || {});
+     node.eachLevel(0, this.config.levelsToShow, function(n) {
+         var d = n._depth - node._depth;
+         if(d > level) {
+             opt.onHide(n);
+             if(opt.execHide) {
+               n.drawn = false; 
+               n.exist = false;
+               fx.hideLabel(n, false);
+             }
+         } else {
+             opt.onShow(n);
+             if(opt.execShow) {
+               n.exist = true;
+             }
+         }
+     });
+     node.drawn= true;
+  },
+  /*
+    Returns the right level to show for the current tree in order to fit in canvas.
+  */  
+  getRightLevelToShow: function(node, canvas) {
+     var config = this.config;
+     var level = config.levelsToShow;
+     var constrained = config.constrained;
+     if(!constrained) return level;
+     while(!this.treeFitsInCanvas(node, canvas, level) && level > 1) { level-- ; }
+     return level;
+  }
+});
+
+/*
+ * File: Loader.js
+ * 
+ */
+
+/*
+   Object: Loader
+
+   Provides methods for loading and serving JSON data.
+*/
+var Loader = {
+     construct: function(json) {
+        var isGraph = ($.type(json) == 'array');
+        var ans = new Graph(this.graphOptions, this.config.Node, this.config.Edge, this.config.Label);
+        if(!isGraph) 
+            //make tree
+            (function (ans, json) {
+                ans.addNode(json);
+                if(json.children) {
+                  for(var i=0, ch = json.children; i<ch.length; i++) {
+                    ans.addAdjacence(json, ch[i]);
+                    arguments.callee(ans, ch[i]);
+                  }
+                }
+            })(ans, json);
+        else
+            //make graph
+            (function (ans, json) {
+                var getNode = function(id) {
+                  for(var i=0, l=json.length; i<l; i++) {
+                    if(json[i].id == id) {
+                      return json[i];
+                    }
+                  }
+                  // The node was not defined in the JSON
+                  // Let's create it
+                  var newNode = {
+                		"id" : id,
+                		"name" : id
+                	};
+                  return ans.addNode(newNode);
+                };
+
+                for(var i=0, l=json.length; i<l; i++) {
+                  ans.addNode(json[i]);
+                  var adj = json[i].adjacencies;
+                  if (adj) {
+                    for(var j=0, lj=adj.length; j<lj; j++) {
+                      var node = adj[j], data = {};
+                      if(typeof adj[j] != 'string') {
+                        data = $.merge(node.data, {});
+                        node = node.nodeTo;
+                      }
+                      ans.addAdjacence(json[i], getNode(node), data);
+                    }
+                  }
+                }
+            })(ans, json);
+
+        return ans;
+    },
+
+    /*
+     Method: loadJSON
+    
+     Loads a JSON structure to the visualization. The JSON structure can be a JSON *tree* or *graph* structure.
+     
+      A JSON tree or graph structure consists of nodes, each having as properties
+       
+       id - (string) A unique identifier for the node
+       name - (string) A node's name
+       data - (object) The data optional property contains a hash (i.e {}) 
+       where you can store all the information you want about this node.
+        
+      For JSON *Tree* structures, there's an extra optional property *children* of type Array which contains the node's children.
+      
+      Example:
+
+      (start code js)
+        var json = {  
+          "id": "aUniqueIdentifier",  
+          "name": "usually a nodes name",  
+          "data": {
+            "some key": "some value",
+            "some other key": "some other value"
+           },  
+          "children": [ *other nodes or empty* ]  
+        };  
+      (end code)
+        
+        JSON *Graph* structures consist of an array of nodes, each specifying the nodes to which the current node is connected. 
+        For JSON *Graph* structures, the *children* property is replaced by the *adjacencies* property.
+        
+        There are two types of *Graph* structures, *simple* and *extended* graph structures.
+        
+        For *simple* Graph structures, the adjacencies property contains an array of strings, each specifying the 
+        id of the node connected to the main node.
+        
+        Example:
+        
+        (start code js)
+        var json = [  
+          {  
+            "id": "aUniqueIdentifier",  
+            "name": "usually a nodes name",  
+            "data": {
+              "some key": "some value",
+              "some other key": "some other value"
+             },  
+            "adjacencies": ["anotherUniqueIdentifier", "yetAnotherUniqueIdentifier", 'etc']  
+          },
+
+          'other nodes go here...' 
+        ];          
+        (end code)
+        
+        For *extended Graph structures*, the adjacencies property contains an array of Adjacency objects that have as properties
+        
+        nodeTo - (string) The other node connected by this adjacency.
+        data - (object) A data property, where we can store custom key/value information.
+        
+        Example:
+        
+        (start code js)
+        var json = [  
+          {  
+            "id": "aUniqueIdentifier",  
+            "name": "usually a nodes name",  
+            "data": {
+              "some key": "some value",
+              "some other key": "some other value"
+             },  
+            "adjacencies": [  
+            {  
+              nodeTo:"aNodeId",  
+              data: {} //put whatever you want here  
+            },
+            'other adjacencies go here...'  
+          },
+
+          'other nodes go here...' 
+        ];          
+        (end code)
+       
+       About the data property:
+       
+       As described before, you can store custom data in the *data* property of JSON *nodes* and *adjacencies*. 
+       You can use almost any string as key for the data object. Some keys though are reserved by the toolkit, and 
+       have special meanings. This is the case for keys starting with a dollar sign, for example, *$width*.
+       
+       For JSON *node* objects, adding dollar prefixed properties that match the names of the options defined in 
+       <Options.Node> will override the general value for that option with that particular value. For this to work 
+       however, you do have to set *overridable = true* in <Options.Node>.
+       
+       The same thing is true for JSON adjacencies. Dollar prefixed data properties will alter values set in <Options.Edge> 
+       if <Options.Edge> has *overridable = true*.
+       
+       When loading JSON data into TreeMaps, the *data* property must contain a value for the *$area* key, 
+       since this is the value which will be taken into account when creating the layout. 
+       The same thing goes for the *$color* parameter.
+       
+       In JSON Nodes you can use also *$label-* prefixed properties to refer to <Options.Label> properties. For example, 
+       *$label-size* will refer to <Options.Label> size property. Also, in JSON nodes and adjacencies you can set 
+       canvas specific properties individually by using the *$canvas-* prefix. For example, *$canvas-shadowBlur* will refer 
+       to the *shadowBlur* property.
+       
+       These properties can also be accessed after loading the JSON data from <Graph.Nodes> and <Graph.Adjacences> 
+       by using <Accessors>. For more information take a look at the <Graph> and <Accessors> documentation.
+       
+       Finally, these properties can also be used to create advanced animations like with <Options.NodeStyles>. For more 
+       information about creating animations please take a look at the <Graph.Plot> and <Graph.Plot.animate> documentation.
+       
+       loadJSON Parameters:
+    
+        json - A JSON Tree or Graph structure.
+        i - For Graph structures only. Sets the indexed node as root for the visualization.
+
+    */
+    loadJSON: function(json, i) {
+      this.json = json;
+      //if they're canvas labels erase them.
+      if(this.labels && this.labels.clearLabels) {
+        this.labels.clearLabels(true);
+      }
+      this.graph = this.construct(json);
+      if($.type(json) != 'array'){
+        this.root = json.id;
+      } else {
+        this.root = json[i? i : 0].id;
+      }
+    },
+    
+    /*
+      Method: toJSON
+   
+      Returns a JSON tree/graph structure from the visualization's <Graph>. 
+      See <Loader.loadJSON> for the graph formats available.
+      
+      See also:
+      
+      <Loader.loadJSON>
+      
+      Parameters:
+      
+      type - (string) Default's "tree". The type of the JSON structure to be returned. 
+      Possible options are "tree" or "graph".
+    */    
+    toJSON: function(type) {
+      type = type || "tree";
+      if(type == 'tree') {
+        var ans = {};
+        var rootNode = this.graph.getNode(this.root);
+        var ans = (function recTree(node) {
+          var ans = {};
+          ans.id = node.id;
+          ans.name = node.name;
+          ans.data = node.data;
+          var ch =[];
+          node.eachSubnode(function(n) {
+            ch.push(recTree(n));
+          });
+          ans.children = ch;
+          return ans;
+        })(rootNode);
+        return ans;
+      } else {
+        var ans = [];
+        var T = !!this.graph.getNode(this.root).visited;
+        this.graph.eachNode(function(node) {
+          var ansNode = {};
+          ansNode.id = node.id;
+          ansNode.name = node.name;
+          ansNode.data = node.data;
+          var adjs = [];
+          node.eachAdjacency(function(adj) {
+            var nodeTo = adj.nodeTo;
+            if(!!nodeTo.visited === T) {
+              var ansAdj = {};
+              ansAdj.nodeTo = nodeTo.id;
+              ansAdj.data = adj.data;
+              adjs.push(ansAdj);
+            }
+          });
+          ansNode.adjacencies = adjs;
+          ans.push(ansNode);
+          node.visited = !T;
+        });
+        return ans;
+      }
+    }
+};
+
+
+
+/*
+ * File: Layouts.js
+ * 
+ * Implements base Tree and Graph layouts.
+ *
+ * Description:
+ *
+ * Implements base Tree and Graph layouts like Radial, Tree, etc.
+ * 
+ */
+
+/*
+ * Object: Layouts
+ * 
+ * Parent object for common layouts.
+ *
+ */
+var Layouts = $jit.Layouts = {};
+
+
+//Some util shared layout functions are defined here.
+var NodeDim = {
+  label: null,
+  
+  compute: function(graph, prop, opt) {
+    this.initializeLabel(opt);
+    var label = this.label, style = label.style;
+    graph.eachNode(function(n) {
+      var autoWidth  = n.getData('autoWidth'),
+          autoHeight = n.getData('autoHeight');
+      if(autoWidth || autoHeight) {
+        //delete dimensions since these are
+        //going to be overridden now.
+        delete n.data.$width;
+        delete n.data.$height;
+        delete n.data.$dim;
+        
+        var width  = n.getData('width'),
+            height = n.getData('height');
+        //reset label dimensions
+        style.width  = autoWidth? 'auto' : width + 'px';
+        style.height = autoHeight? 'auto' : height + 'px';
+        
+        //TODO(nico) should let the user choose what to insert here.
+        label.innerHTML = n.name;
+        
+        var offsetWidth  = label.offsetWidth,
+            offsetHeight = label.offsetHeight;
+        var type = n.getData('type');
+        if($.indexOf(['circle', 'square', 'triangle', 'star'], type) === -1) {
+          n.setData('width', offsetWidth);
+          n.setData('height', offsetHeight);
+        } else {
+          var dim = offsetWidth > offsetHeight? offsetWidth : offsetHeight;
+          n.setData('width', dim);
+          n.setData('height', dim);
+          n.setData('dim', dim); 
+        }
+      }
+    });
+  },
+  
+  initializeLabel: function(opt) {
+    if(!this.label) {
+      this.label = document.createElement('div');
+      document.body.appendChild(this.label);
+    }
+    this.setLabelStyles(opt);
+  },
+  
+  setLabelStyles: function(opt) {
+    $.extend(this.label.style, {
+      'visibility': 'hidden',
+      'position': 'absolute',
+      'width': 'auto',
+      'height': 'auto'
+    });
+    this.label.className = 'jit-autoadjust-label';
+  }
+};
+
+
+/*
+ * Class: Layouts.Tree
+ * 
+ * Implements a Tree Layout.
+ * 
+ * Implemented By:
+ * 
+ * <ST>
+ * 
+ * Inspired by:
+ * 
+ * Drawing Trees (Andrew J. Kennedy) <http://research.microsoft.com/en-us/um/people/akenn/fun/drawingtrees.pdf>
+ * 
+ */
+Layouts.Tree = (function() {
+  //Layout functions
+  var slice = Array.prototype.slice;
+
+  /*
+     Calculates the max width and height nodes for a tree level
+  */  
+  function getBoundaries(graph, config, level, orn, prop) {
+    var dim = config.Node;
+    var multitree = config.multitree;
+    if (dim.overridable) {
+      var w = -1, h = -1;
+      graph.eachNode(function(n) {
+        if (n._depth == level
+            && (!multitree || ('$orn' in n.data) && n.data.$orn == orn)) {
+          var dw = n.getData('width', prop);
+          var dh = n.getData('height', prop);
+          w = (w < dw) ? dw : w;
+          h = (h < dh) ? dh : h;
+        }
+      });
+      return {
+        'width' : w < 0 ? dim.width : w,
+        'height' : h < 0 ? dim.height : h
+      };
+    } else {
+      return dim;
+    }
+  }
+
+
+  function movetree(node, prop, val, orn) {
+    var p = (orn == "left" || orn == "right") ? "y" : "x";
+    node.getPos(prop)[p] += val;
+  }
+
+
+  function moveextent(extent, val) {
+    var ans = [];
+    $.each(extent, function(elem) {
+      elem = slice.call(elem);
+      elem[0] += val;
+      elem[1] += val;
+      ans.push(elem);
+    });
+    return ans;
+  }
+
+
+  function merge(ps, qs) {
+    if (ps.length == 0)
+      return qs;
+    if (qs.length == 0)
+      return ps;
+    var p = ps.shift(), q = qs.shift();
+    return [ [ p[0], q[1] ] ].concat(merge(ps, qs));
+  }
+
+
+  function mergelist(ls, def) {
+    def = def || [];
+    if (ls.length == 0)
+      return def;
+    var ps = ls.pop();
+    return mergelist(ls, merge(ps, def));
+  }
+
+
+  function fit(ext1, ext2, subtreeOffset, siblingOffset, i) {
+    if (ext1.length <= i || ext2.length <= i)
+      return 0;
+
+    var p = ext1[i][1], q = ext2[i][0];
+    return Math.max(fit(ext1, ext2, subtreeOffset, siblingOffset, ++i)
+        + subtreeOffset, p - q + siblingOffset);
+  }
+
+
+  function fitlistl(es, subtreeOffset, siblingOffset) {
+    function $fitlistl(acc, es, i) {
+      if (es.length <= i)
+        return [];
+      var e = es[i], ans = fit(acc, e, subtreeOffset, siblingOffset, 0);
+      return [ ans ].concat($fitlistl(merge(acc, moveextent(e, ans)), es, ++i));
+    }
+    ;
+    return $fitlistl( [], es, 0);
+  }
+
+
+  function fitlistr(es, subtreeOffset, siblingOffset) {
+    function $fitlistr(acc, es, i) {
+      if (es.length <= i)
+        return [];
+      var e = es[i], ans = -fit(e, acc, subtreeOffset, siblingOffset, 0);
+      return [ ans ].concat($fitlistr(merge(moveextent(e, ans), acc), es, ++i));
+    }
+    ;
+    es = slice.call(es);
+    var ans = $fitlistr( [], es.reverse(), 0);
+    return ans.reverse();
+  }
+
+
+  function fitlist(es, subtreeOffset, siblingOffset, align) {
+    var esl = fitlistl(es, subtreeOffset, siblingOffset), esr = fitlistr(es,
+        subtreeOffset, siblingOffset);
+
+    if (align == "left")
+      esr = esl;
+    else if (align == "right")
+      esl = esr;
+
+    for ( var i = 0, ans = []; i < esl.length; i++) {
+      ans[i] = (esl[i] + esr[i]) / 2;
+    }
+    return ans;
+  }
+
+
+  function design(graph, node, prop, config, orn) {
+    var multitree = config.multitree;
+    var auxp = [ 'x', 'y' ], auxs = [ 'width', 'height' ];
+    var ind = +(orn == "left" || orn == "right");
+    var p = auxp[ind], notp = auxp[1 - ind];
+
+    var cnode = config.Node;
+    var s = auxs[ind], nots = auxs[1 - ind];
+
+    var siblingOffset = config.siblingOffset;
+    var subtreeOffset = config.subtreeOffset;
+    var align = config.align;
+
+    function $design(node, maxsize, acum) {
+      var sval = node.getData(s, prop);
+      var notsval = maxsize
+          || (node.getData(nots, prop));
+
+      var trees = [], extents = [], chmaxsize = false;
+      var chacum = notsval + config.levelDistance;
+      node.eachSubnode(function(n) {
+            if (n.exist
+                && (!multitree || ('$orn' in n.data) && n.data.$orn == orn)) {
+
+              if (!chmaxsize)
+                chmaxsize = getBoundaries(graph, config, n._depth, orn, prop);
+
+              var s = $design(n, chmaxsize[nots], acum + chacum);
+              trees.push(s.tree);
+              extents.push(s.extent);
+            }
+          });
+      var positions = fitlist(extents, subtreeOffset, siblingOffset, align);
+      for ( var i = 0, ptrees = [], pextents = []; i < trees.length; i++) {
+        movetree(trees[i], prop, positions[i], orn);
+        pextents.push(moveextent(extents[i], positions[i]));
+      }
+      var resultextent = [ [ -sval / 2, sval / 2 ] ]
+          .concat(mergelist(pextents));
+      node.getPos(prop)[p] = 0;
+
+      if (orn == "top" || orn == "left") {
+        node.getPos(prop)[notp] = acum;
+      } else {
+        node.getPos(prop)[notp] = -acum;
+      }
+
+      return {
+        tree : node,
+        extent : resultextent
+      };
+    }
+
+    $design(node, false, 0);
+  }
+
+
+  return new Class({
+    /*
+    Method: compute
+    
+    Computes nodes' positions.
+
+     */
+    compute : function(property, computeLevels) {
+      var prop = property || 'start';
+      var node = this.graph.getNode(this.root);
+      $.extend(node, {
+        'drawn' : true,
+        'exist' : true,
+        'selected' : true
+      });
+      NodeDim.compute(this.graph, prop, this.config);
+      if (!!computeLevels || !("_depth" in node)) {
+        this.graph.computeLevels(this.root, 0, "ignore");
+      }
+      
+      this.computePositions(node, prop);
+    },
+
+    computePositions : function(node, prop) {
+      var config = this.config;
+      var multitree = config.multitree;
+      var align = config.align;
+      var indent = align !== 'center' && config.indent;
+      var orn = config.orientation;
+      var orns = multitree ? [ 'top', 'right', 'bottom', 'left' ] : [ orn ];
+      var that = this;
+      $.each(orns, function(orn) {
+        //calculate layout
+          design(that.graph, node, prop, that.config, orn, prop);
+          var i = [ 'x', 'y' ][+(orn == "left" || orn == "right")];
+          //absolutize
+          (function red(node) {
+            node.eachSubnode(function(n) {
+              if (n.exist
+                  && (!multitree || ('$orn' in n.data) && n.data.$orn == orn)) {
+
+                n.getPos(prop)[i] += node.getPos(prop)[i];
+                if (indent) {
+                  n.getPos(prop)[i] += align == 'left' ? indent : -indent;
+                }
+                red(n);
+              }
+            });
+          })(node);
+        });
+    }
+  });
+  
+})();
+
+/*
+ * File: Spacetree.js
+ */
+
+/*
+   Class: ST
+   
+  A Tree layout with advanced contraction and expansion animations.
+     
+  Inspired by:
+ 
+  SpaceTree: Supporting Exploration in Large Node Link Tree, Design Evolution and Empirical Evaluation (Catherine Plaisant, Jesse Grosjean, Benjamin B. Bederson) 
+  <http://hcil.cs.umd.edu/trs/2002-05/2002-05.pdf>
+  
+  Drawing Trees (Andrew J. Kennedy) <http://research.microsoft.com/en-us/um/people/akenn/fun/drawingtrees.pdf>
+  
+  Note:
+ 
+  This visualization was built and engineered from scratch, taking only the papers as inspiration, and only shares some features with the visualization described in those papers.
+ 
+  Implements:
+  
+  All <Loader> methods
+  
+  Constructor Options:
+  
+  Inherits options from
+  
+  - <Options.Canvas>
+  - <Options.Controller>
+  - <Options.Tree>
+  - <Options.Node>
+  - <Options.Edge>
+  - <Options.Label>
+  - <Options.Events>
+  - <Options.Tips>
+  - <Options.NodeStyles>
+  - <Options.Navigation>
+  
+  Additionally, there are other parameters and some default values changed
+  
+  constrained - (boolean) Default's *true*. Whether to show the entire tree when loaded or just the number of levels specified by _levelsToShow_.
+  levelsToShow - (number) Default's *2*. The number of levels to show for a subtree. This number is relative to the selected node.
+  levelDistance - (number) Default's *30*. The distance between two consecutive levels of the tree.
+  Node.type - Described in <Options.Node>. Default's set to *rectangle*.
+  offsetX - (number) Default's *0*. The x-offset distance from the selected node to the center of the canvas.
+  offsetY - (number) Default's *0*. The y-offset distance from the selected node to the center of the canvas.
+  duration - Described in <Options.Fx>. It's default value has been changed to *700*.
+  
+  Instance Properties:
+  
+  canvas - Access a <Canvas> instance.
+  graph - Access a <Graph> instance.
+  op - Access a <ST.Op> instance.
+  fx - Access a <ST.Plot> instance.
+  labels - Access a <ST.Label> interface implementation.
+
+ */
+
+$jit.ST= (function() {
+    // Define some private methods first...
+    // Nodes in path
+    var nodesInPath = [];
+    // Nodes to contract
+    function getNodesToHide(node) {
+      node = node || this.clickedNode;
+      if(!this.config.constrained) {
+        return [];
+      }
+      var Geom = this.geom;
+      var graph = this.graph;
+      var canvas = this.canvas;
+      var level = node._depth, nodeArray = [];
+  	  graph.eachNode(function(n) {
+          if(n.exist && !n.selected) {
+              if(n.isDescendantOf(node.id)) {
+                if(n._depth <= level) nodeArray.push(n);
+              } else {
+                nodeArray.push(n);
+              }
+          }
+  	  });
+  	  var leafLevel = Geom.getRightLevelToShow(node, canvas);
+  	  node.eachLevel(leafLevel, leafLevel, function(n) {
+          if(n.exist && !n.selected) nodeArray.push(n);
+  	  });
+  	    
+  	  for (var i = 0; i < nodesInPath.length; i++) {
+  	    var n = this.graph.getNode(nodesInPath[i]);
+  	    if(!n.isDescendantOf(node.id)) {
+  	      nodeArray.push(n);
+  	    }
+  	  } 
+  	  return nodeArray;       
+    };
+    // Nodes to expand
+     function getNodesToShow(node) {
+        var nodeArray = [], config = this.config;
+        node = node || this.clickedNode;
+        this.clickedNode.eachLevel(0, config.levelsToShow, function(n) {
+            if(config.multitree && !('$orn' in n.data) 
+            		&& n.anySubnode(function(ch){ return ch.exist && !ch.drawn; })) {
+            	nodeArray.push(n);
+            } else if(n.drawn && !n.anySubnode("drawn")) {
+              nodeArray.push(n);
+            }
+        });
+        return nodeArray;
+     };
+    // Now define the actual class.
+    return new Class({
+    
+        Implements: [Loader, Extras, Layouts.Tree],
+        
+        initialize: function(controller) {            
+          var $ST = $jit.ST;
+          
+          var config= {
+                levelsToShow: 2,
+                levelDistance: 30,
+                constrained: true,                
+                Node: {
+                  type: 'rectangle'
+                },
+                duration: 700,
+                offsetX: 0,
+                offsetY: 0
+            };
+            
+            this.controller = this.config = $.merge(
+                Options("Canvas", "Fx", "Tree", "Node", "Edge", "Controller", 
+                    "Tips", "NodeStyles", "Events", "Navigation", "Label"), config, controller);
+
+            var canvasConfig = this.config;
+            if(canvasConfig.useCanvas) {
+              this.canvas = canvasConfig.useCanvas;
+              this.config.labelContainer = this.canvas.id + '-label';
+            } else {
+              if(canvasConfig.background) {
+                canvasConfig.background = $.merge({
+                  type: 'Circles'
+                }, canvasConfig.background);
+              }
+              this.canvas = new Canvas(this, canvasConfig);
+              this.config.labelContainer = (typeof canvasConfig.injectInto == 'string'? canvasConfig.injectInto : canvasConfig.injectInto.id) + '-label';
+            }
+
+            this.graphOptions = {
+                'klass': Complex
+            };
+            this.graph = new Graph(this.graphOptions, this.config.Node, this.config.Edge);
+            this.labels = new $ST.Label[canvasConfig.Label.type](this);
+            this.fx = new $ST.Plot(this, $ST);
+            this.op = new $ST.Op(this);
+            this.group = new $ST.Group(this);
+            this.geom = new $ST.Geom(this);
+            this.clickedNode=  null;
+            // initialize extras
+            this.initializeExtras();
+        },
+    
+        /*
+         Method: plot
+        
+         Plots the <ST>. This is a shortcut to *fx.plot*.
+
+        */  
+        plot: function() { this.fx.plot(this.controller); },
+    
+      
+        /*
+         Method: switchPosition
+        
+         Switches the tree orientation.
+
+         Parameters:
+
+        pos - (string) The new tree orientation. Possible values are "top", "left", "right" and "bottom".
+        method - (string) Set this to "animate" if you want to animate the tree when switching its position. You can also set this parameter to "replot" to just replot the subtree.
+        onComplete - (optional|object) This callback is called once the "switching" animation is complete.
+
+         Example:
+
+         (start code js)
+           st.switchPosition("right", "animate", {
+            onComplete: function() {
+              alert('completed!');
+            } 
+           });
+         (end code)
+        */  
+        switchPosition: function(pos, method, onComplete) {
+          var Geom = this.geom, Plot = this.fx, that = this;
+          if(!Plot.busy) {
+              Plot.busy = true;
+              this.contract({
+                  onComplete: function() {
+                      Geom.switchOrientation(pos);
+                      that.compute('end', false);
+                      Plot.busy = false;
+                      if(method == 'animate') {
+                    	  that.onClick(that.clickedNode.id, onComplete);  
+                      } else if(method == 'replot') {
+                    	  that.select(that.clickedNode.id, onComplete);
+                      }
+                  }
+              }, pos);
+          }
+        },
+
+        /*
+        Method: switchAlignment
+       
+        Switches the tree alignment.
+
+        Parameters:
+
+       align - (string) The new tree alignment. Possible values are "left", "center" and "right".
+       method - (string) Set this to "animate" if you want to animate the tree after aligning its position. You can also set this parameter to "replot" to just replot the subtree.
+       onComplete - (optional|object) This callback is called once the "switching" animation is complete.
+
+        Example:
+
+        (start code js)
+          st.switchAlignment("right", "animate", {
+           onComplete: function() {
+             alert('completed!');
+           } 
+          });
+        (end code)
+       */  
+       switchAlignment: function(align, method, onComplete) {
+        this.config.align = align;
+        if(method == 'animate') {
+        	this.select(this.clickedNode.id, onComplete);
+        } else if(method == 'replot') {
+        	this.onClick(this.clickedNode.id, onComplete);	
+        }
+       },
+
+       /*
+        Method: addNodeInPath
+       
+        Adds a node to the current path as selected node. The selected node will be visible (as in non-collapsed) at all times.
+        
+
+        Parameters:
+
+       id - (string) A <Graph.Node> id.
+
+        Example:
+
+        (start code js)
+          st.addNodeInPath("nodeId");
+        (end code)
+       */  
+       addNodeInPath: function(id) {
+           nodesInPath.push(id);
+           this.select((this.clickedNode && this.clickedNode.id) || this.root);
+       },       
+
+       /*
+       Method: clearNodesInPath
+      
+       Removes all nodes tagged as selected by the <ST.addNodeInPath> method.
+       
+       See also:
+       
+       <ST.addNodeInPath>
+     
+       Example:
+
+       (start code js)
+         st.clearNodesInPath();
+       (end code)
+      */  
+       clearNodesInPath: function(id) {
+           nodesInPath.length = 0;
+           this.select((this.clickedNode && this.clickedNode.id) || this.root);
+       },
+        
+       /*
+         Method: refresh
+        
+         Computes positions and plots the tree.
+         
+       */
+       refresh: function() {
+           this.reposition();
+           this.select((this.clickedNode && this.clickedNode.id) || this.root);
+       },    
+
+       reposition: function() {
+            this.graph.computeLevels(this.root, 0, "ignore");
+             this.geom.setRightLevelToShow(this.clickedNode, this.canvas);
+            this.graph.eachNode(function(n) {
+                if(n.exist) n.drawn = true;
+            });
+            this.compute('end');
+        },
+        
+        requestNodes: function(node, onComplete) {
+          var handler = $.merge(this.controller, onComplete), 
+          lev = this.config.levelsToShow;
+          if(handler.request) {
+              var leaves = [], d = node._depth;
+              node.eachLevel(0, lev, function(n) {
+                  if(n.drawn && 
+                   !n.anySubnode()) {
+                   leaves.push(n);
+                   n._level = lev - (n._depth - d);
+                  }
+              });
+              this.group.requestNodes(leaves, handler);
+          }
+            else
+              handler.onComplete();
+        },
+     
+        contract: function(onComplete, switched) {
+          var orn  = this.config.orientation;
+          var Geom = this.geom, Group = this.group;
+          if(switched) Geom.switchOrientation(switched);
+          var nodes = getNodesToHide.call(this);
+          if(switched) Geom.switchOrientation(orn);
+          Group.contract(nodes, $.merge(this.controller, onComplete));
+        },
+      
+         move: function(node, onComplete) {
+            this.compute('end', false);
+            var move = onComplete.Move, offset = {
+                'x': move.offsetX,
+                'y': move.offsetY 
+            };
+            if(move.enable) {
+                this.geom.translate(node.endPos.add(offset).$scale(-1), "end");
+            }
+            this.fx.animate($.merge(this.controller, { modes: ['linear'] }, onComplete));
+         },
+      
+        expand: function (node, onComplete) {
+            var nodeArray = getNodesToShow.call(this, node);
+            this.group.expand(nodeArray, $.merge(this.controller, onComplete));
+        },
+    
+        selectPath: function(node) {
+          var that = this;
+          this.graph.eachNode(function(n) { n.selected = false; }); 
+          function path(node) {
+              if(node == null || node.selected) return;
+              node.selected = true;
+              $.each(that.group.getSiblings([node])[node.id], 
+              function(n) { 
+                   n.exist = true; 
+                   n.drawn = true; 
+              });    
+              var parents = node.getParents();
+              parents = (parents.length > 0)? parents[0] : null;
+              path(parents);
+          };
+          for(var i=0, ns = [node.id].concat(nodesInPath); i < ns.length; i++) {
+              path(this.graph.getNode(ns[i]));
+          }
+        },
+      
+        /*
+        Method: setRoot
+     
+         Switches the current root node. Changes the topology of the Tree.
+     
+        Parameters:
+           id - (string) The id of the node to be set as root.
+           method - (string) Set this to "animate" if you want to animate the tree after adding the subtree. You can also set this parameter to "replot" to just replot the subtree.
+           onComplete - (optional|object) An action to perform after the animation (if any).
+ 
+        Example:
+
+        (start code js)
+          st.setRoot('nodeId', 'animate', {
+             onComplete: function() {
+               alert('complete!');
+             }
+          });
+        (end code)
+     */
+     setRoot: function(id, method, onComplete) {
+        	if(this.busy) return;
+        	this.busy = true;
+          var that = this, canvas = this.canvas;
+        	var rootNode = this.graph.getNode(this.root);
+        	var clickedNode = this.graph.getNode(id);
+        	function $setRoot() {
+            	if(this.config.multitree && clickedNode.data.$orn) {
+            		var orn = clickedNode.data.$orn;
+            		var opp = {
+            				'left': 'right',
+            				'right': 'left',
+            				'top': 'bottom',
+            				'bottom': 'top'
+            		}[orn];
+            		rootNode.data.$orn = opp;
+            		(function tag(rootNode) {
+                		rootNode.eachSubnode(function(n) {
+                			if(n.id != id) {
+                				n.data.$orn = opp;
+                				tag(n);
+                			}
+                		});
+            		})(rootNode);
+            		delete clickedNode.data.$orn;
+            	}
+            	this.root = id;
+            	this.clickedNode = clickedNode;
+            	this.graph.computeLevels(this.root, 0, "ignore");
+            	this.geom.setRightLevelToShow(clickedNode, canvas, {
+            	  execHide: false,
+            	  onShow: function(node) {
+            	    if(!node.drawn) {
+                    node.drawn = true;
+                    node.setData('alpha', 1, 'end');
+                    node.setData('alpha', 0);
+                    node.pos.setc(clickedNode.pos.x, clickedNode.pos.y);
+            	    }
+            	  }
+            	});
+              this.compute('end');
+              this.busy = true;
+              this.fx.animate({
+                modes: ['linear', 'node-property:alpha'],
+                onComplete: function() {
+                  that.busy = false;
+                  that.onClick(id, {
+                    onComplete: function() {
+                      onComplete && onComplete.onComplete();
+                    }
+                  });
+                }
+              });
+        	}
+
+        	// delete previous orientations (if any)
+        	delete rootNode.data.$orns;
+
+        	if(method == 'animate') {
+        	  $setRoot.call(this);
+        	  that.selectPath(clickedNode);
+        	} else if(method == 'replot') {
+        		$setRoot.call(this);
+        		this.select(this.root);
+        	}
+     },
+
+     /*
+           Method: addSubtree
+        
+            Adds a subtree.
+        
+           Parameters:
+              subtree - (object) A JSON Tree object. See also <Loader.loadJSON>.
+              method - (string) Set this to "animate" if you want to animate the tree after adding the subtree. You can also set this parameter to "replot" to just replot the subtree.
+              onComplete - (optional|object) An action to perform after the animation (if any).
+    
+           Example:
+
+           (start code js)
+             st.addSubtree(json, 'animate', {
+                onComplete: function() {
+                  alert('complete!');
+                }
+             });
+           (end code)
+        */
+        addSubtree: function(subtree, method, onComplete) {
+            if(method == 'replot') {
+                this.op.sum(subtree, $.extend({ type: 'replot' }, onComplete || {}));
+            } else if (method == 'animate') {
+                this.op.sum(subtree, $.extend({ type: 'fade:seq' }, onComplete || {}));
+            }
+        },
+    
+        /*
+           Method: removeSubtree
+        
+            Removes a subtree.
+        
+           Parameters:
+              id - (string) The _id_ of the subtree to be removed.
+              removeRoot - (boolean) Default's *false*. Remove the root of the subtree or only its subnodes.
+              method - (string) Set this to "animate" if you want to animate the tree after removing the subtree. You can also set this parameter to "replot" to just replot the subtree.
+              onComplete - (optional|object) An action to perform after the animation (if any).
+
+          Example:
+
+          (start code js)
+            st.removeSubtree('idOfSubtreeToBeRemoved', false, 'animate', {
+              onComplete: function() {
+                alert('complete!');
+              }
+            });
+          (end code)
+    
+        */
+        removeSubtree: function(id, removeRoot, method, onComplete) {
+            var node = this.graph.getNode(id), subids = [];
+            node.eachLevel(+!removeRoot, false, function(n) {
+                subids.push(n.id);
+            });
+            if(method == 'replot') {
+                this.op.removeNode(subids, $.extend({ type: 'replot' }, onComplete || {}));
+            } else if (method == 'animate') {
+                this.op.removeNode(subids, $.extend({ type: 'fade:seq'}, onComplete || {}));
+            }
+        },
+    
+        /*
+           Method: select
+        
+            Selects a node in the <ST> without performing an animation. Useful when selecting 
+            nodes which are currently hidden or deep inside the tree.
+
+          Parameters:
+            id - (string) The id of the node to select.
+            onComplete - (optional|object) an onComplete callback.
+
+          Example:
+          (start code js)
+            st.select('mynodeid', {
+              onComplete: function() {
+                alert('complete!');
+              }
+            });
+          (end code)
+        */
+        select: function(id, onComplete) {
+            var group = this.group, geom = this.geom;
+            var node=  this.graph.getNode(id), canvas = this.canvas;
+            var root  = this.graph.getNode(this.root);
+            var complete = $.merge(this.controller, onComplete);
+            var that = this;
+    
+            complete.onBeforeCompute(node);
+            this.selectPath(node);
+            this.clickedNode= node;
+            this.requestNodes(node, {
+                onComplete: function(){
+                    group.hide(group.prepare(getNodesToHide.call(that)), complete);
+                    geom.setRightLevelToShow(node, canvas);
+                    that.compute("current");
+                    that.graph.eachNode(function(n) { 
+                        var pos = n.pos.getc(true);
+                        n.startPos.setc(pos.x, pos.y);
+                        n.endPos.setc(pos.x, pos.y);
+                        n.visited = false; 
+                    });
+                    var offset = { x: complete.offsetX, y: complete.offsetY };
+                    that.geom.translate(node.endPos.add(offset).$scale(-1), ["start", "current", "end"]);
+                    group.show(getNodesToShow.call(that));              
+                    that.plot();
+                    complete.onAfterCompute(that.clickedNode);
+                    complete.onComplete();
+                }
+            });     
+        },
+    
+      /*
+         Method: onClick
+    
+        Animates the <ST> to center the node specified by *id*.
+            
+        Parameters:
+        
+        id - (string) A node id.
+        options - (optional|object) A group of options and callbacks described below.
+        onComplete - (object) An object callback called when the animation finishes.
+        Move - (object) An object that has as properties _offsetX_ or _offsetY_ for adding some offset position to the centered node.
+
+        Example:
+
+        (start code js)
+          st.onClick('mynodeid', {
+	          Move: {
+	          	enable: true,
+	            offsetX: 30,
+	            offsetY: 5
+	          },
+	          onComplete: function() {
+	              alert('yay!');
+	          }
+          });
+        (end code)
+    
+        */    
+      onClick: function (id, options) {
+        var canvas = this.canvas, that = this, Geom = this.geom, config = this.config;
+        var innerController = {
+            Move: {
+        	    enable: true,
+              offsetX: config.offsetX || 0,
+              offsetY: config.offsetY || 0  
+            },
+            setRightLevelToShowConfig: false,
+            onBeforeRequest: $.empty,
+            onBeforeContract: $.empty,
+            onBeforeMove: $.empty,
+            onBeforeExpand: $.empty
+        };
+        var complete = $.merge(this.controller, innerController, options);
+        
+        if(!this.busy) {
+            this.busy = true;
+            var node = this.graph.getNode(id);
+            this.selectPath(node, this.clickedNode);
+           	this.clickedNode = node;
+            complete.onBeforeCompute(node);
+            complete.onBeforeRequest(node);
+            this.requestNodes(node, {
+                onComplete: function() {
+                    complete.onBeforeContract(node);
+                    that.contract({
+                        onComplete: function() {
+                            Geom.setRightLevelToShow(node, canvas, complete.setRightLevelToShowConfig);
+                            complete.onBeforeMove(node);
+                            that.move(node, {
+                                Move: complete.Move,
+                                onComplete: function() {
+                                    complete.onBeforeExpand(node);
+                                    that.expand(node, {
+                                        onComplete: function() {
+                                            that.busy = false;
+                                            complete.onAfterCompute(id);
+                                            complete.onComplete();
+                                        }
+                                    }); // expand
+                                }
+                            }); // move
+                        }
+                    });// contract
+                }
+            });// request
+        }
+      }
+    });
+
+})();
+
+$jit.ST.$extend = true;
+
+/*
+   Class: ST.Op
+    
+   Custom extension of <Graph.Op>.
+
+   Extends:
+
+   All <Graph.Op> methods
+   
+   See also:
+   
+   <Graph.Op>
+
+*/
+$jit.ST.Op = new Class({
+
+  Implements: Graph.Op
+    
+});
+
+/*
+    
+     Performs operations on group of nodes.
+
+*/
+$jit.ST.Group = new Class({
+    
+    initialize: function(viz) {
+        this.viz = viz;
+        this.canvas = viz.canvas;
+        this.config = viz.config;
+        this.animation = new Animation;
+        this.nodes = null;
+    },
+    
+    /*
+    
+       Calls the request method on the controller to request a subtree for each node. 
+    */
+    requestNodes: function(nodes, controller) {
+        var counter = 0, len = nodes.length, nodeSelected = {};
+        var complete = function() { controller.onComplete(); };
+        var viz = this.viz;
+        if(len == 0) complete();
+        for(var i=0; i<len; i++) {
+            nodeSelected[nodes[i].id] = nodes[i];
+            controller.request(nodes[i].id, nodes[i]._level, {
+                onComplete: function(nodeId, data) {
+                    if(data && data.children) {
+                        data.id = nodeId;
+                        viz.op.sum(data, { type: 'nothing' });
+                    }
+                    if(++counter == len) {
+                        viz.graph.computeLevels(viz.root, 0);
+                        complete();
+                    }
+                }
+            });
+        }
+    },
+    
+    /*
+    
+       Collapses group of nodes. 
+    */
+    contract: function(nodes, controller) {
+        var viz = this.viz;
+        var that = this;
+
+        nodes = this.prepare(nodes);
+        this.animation.setOptions($.merge(controller, {
+            $animating: false,
+            compute: function(delta) {
+              if(delta == 1) delta = 0.99;
+              that.plotStep(1 - delta, controller, this.$animating);
+              this.$animating = 'contract';
+            },
+            
+            complete: function() {
+                that.hide(nodes, controller);
+            }       
+        })).start();
+    },
+    
+    hide: function(nodes, controller) {
+        var viz = this.viz;
+        for(var i=0; i<nodes.length; i++) {
+            // TODO nodes are requested on demand, but not
+            // deleted when hidden. Would that be a good feature?
+            // Currently that feature is buggy, so I'll turn it off
+            // Actually this feature is buggy because trimming should take
+            // place onAfterCompute and not right after collapsing nodes.
+            if (true || !controller || !controller.request) {
+                nodes[i].eachLevel(1, false, function(elem){
+                    if (elem.exist) {
+                        $.extend(elem, {
+                            'drawn': false,
+                            'exist': false
+                        });
+                    }
+                });
+            } else {
+                var ids = [];
+                nodes[i].eachLevel(1, false, function(n) {
+                    ids.push(n.id);
+                });
+                viz.op.removeNode(ids, { 'type': 'nothing' });
+                viz.labels.clearLabels();
+            }
+        }
+        controller.onComplete();
+    },    
+    
+
+    /*
+       Expands group of nodes. 
+    */
+    expand: function(nodes, controller) {
+        var that = this;
+        this.show(nodes);
+        this.animation.setOptions($.merge(controller, {
+            $animating: false,
+            compute: function(delta) {
+                that.plotStep(delta, controller, this.$animating);
+                this.$animating = 'expand';
+            },
+            
+            complete: function() {
+                that.plotStep(undefined, controller, false);
+                controller.onComplete();
+            }       
+        })).start();
+        
+    },
+    
+    show: function(nodes) {
+        var config = this.config;
+        this.prepare(nodes);
+        $.each(nodes, function(n) {
+        	// check for root nodes if multitree
+        	if(config.multitree && !('$orn' in n.data)) {
+        		delete n.data.$orns;
+        		var orns = ' ';
+        		n.eachSubnode(function(ch) {
+        			if(('$orn' in ch.data) 
+        					&& orns.indexOf(ch.data.$orn) < 0 
+        					&& ch.exist && !ch.drawn) {
+        				orns += ch.data.$orn + ' ';
+        			}
+        		});
+        		n.data.$orns = orns;
+        	}
+            n.eachLevel(0, config.levelsToShow, function(n) {
+            	if(n.exist) n.drawn = true;
+            });     
+        });
+    },
+    
+    prepare: function(nodes) {
+        this.nodes = this.getNodesWithChildren(nodes);
+        return this.nodes;
+    },
+    
+    /*
+       Filters an array of nodes leaving only nodes with children.
+    */
+    getNodesWithChildren: function(nodes) {
+        var ans = [], config = this.config, root = this.viz.root;
+        nodes.sort(function(a, b) { return (a._depth <= b._depth) - (a._depth >= b._depth); });
+        for(var i=0; i<nodes.length; i++) {
+            if(nodes[i].anySubnode("exist")) {
+            	for (var j = i+1, desc = false; !desc && j < nodes.length; j++) {
+                    if(!config.multitree || '$orn' in nodes[j].data) {
+                		desc = desc || nodes[i].isDescendantOf(nodes[j].id);                    	
+                    }
+                }
+                if(!desc) ans.push(nodes[i]);
+            }
+        }
+        return ans;
+    },
+    
+    plotStep: function(delta, controller, animating) {
+        var viz = this.viz,
+        config = this.config,
+        canvas = viz.canvas, 
+        ctx = canvas.getCtx(),
+        nodes = this.nodes;
+        var i, node;
+        // hide nodes that are meant to be collapsed/expanded
+        var nds = {};
+        for(i=0; i<nodes.length; i++) {
+          node = nodes[i];
+          nds[node.id] = [];
+          var root = config.multitree && !('$orn' in node.data);
+          var orns = root && node.data.$orns;
+          node.eachSubgraph(function(n) { 
+            // TODO(nico): Cleanup
+        	  // special check for root node subnodes when
+        	  // multitree is checked.
+        	  if(root && orns && orns.indexOf(n.data.$orn) > 0 
+        			  && n.drawn) {
+        		  n.drawn = false;
+                  nds[node.id].push(n);
+              } else if((!root || !orns) && n.drawn) {
+                n.drawn = false;
+                nds[node.id].push(n);
+              }
+            });	
+            node.drawn = true;
+        }
+        // plot the whole (non-scaled) tree
+        if(nodes.length > 0) viz.fx.plot();
+        // show nodes that were previously hidden
+        for(i in nds) {
+          $.each(nds[i], function(n) { n.drawn = true; });
+        }
+        // plot each scaled subtree
+        for(i=0; i<nodes.length; i++) {
+          node = nodes[i];
+          ctx.save();
+          viz.fx.plotSubtree(node, controller, delta, animating);                
+          ctx.restore();
+        }
+      },
+
+      getSiblings: function(nodes) {
+        var siblings = {};
+        $.each(nodes, function(n) {
+            var par = n.getParents();
+            if (par.length == 0) {
+                siblings[n.id] = [n];
+            } else {
+                var ans = [];
+                par[0].eachSubnode(function(sn) {
+                    ans.push(sn);
+                });
+                siblings[n.id] = ans;
+            }
+        });
+        return siblings;
+    }
+});
+
+/*
+   ST.Geom
+
+   Performs low level geometrical computations.
+
+   Access:
+
+   This instance can be accessed with the _geom_ parameter of the st instance created.
+
+   Example:
+
+   (start code js)
+    var st = new ST(canvas, config);
+    st.geom.translate //or can also call any other <ST.Geom> method
+   (end code)
+
+*/
+
+$jit.ST.Geom = new Class({
+    Implements: Graph.Geom,
+    /*
+       Changes the tree current orientation to the one specified.
+
+       You should usually use <ST.switchPosition> instead.
+    */  
+    switchOrientation: function(orn) {
+    	this.config.orientation = orn;
+    },
+
+    /*
+       Makes a value dispatch according to the current layout
+       Works like a CSS property, either _top-right-bottom-left_ or _top|bottom - left|right_.
+     */
+    dispatch: function() {
+    	  // TODO(nico) should store Array.prototype.slice.call somewhere.
+        var args = Array.prototype.slice.call(arguments);
+        var s = args.shift(), len = args.length;
+        var val = function(a) { return typeof a == 'function'? a() : a; };
+        if(len == 2) {
+            return (s == "top" || s == "bottom")? val(args[0]) : val(args[1]);
+        } else if(len == 4) {
+            switch(s) {
+                case "top": return val(args[0]);
+                case "right": return val(args[1]);
+                case "bottom": return val(args[2]);
+                case "left": return val(args[3]);
+            }
+        }
+        return undefined;
+    },
+
+    /*
+       Returns label height or with, depending on the tree current orientation.
+    */  
+    getSize: function(n, invert) {
+        var data = n.data, config = this.config;
+        var siblingOffset = config.siblingOffset;
+        var s = (config.multitree 
+        		&& ('$orn' in data) 
+        		&& data.$orn) || config.orientation;
+        var w = n.getData('width') + siblingOffset;
+        var h = n.getData('height') + siblingOffset;
+        if(!invert)
+            return this.dispatch(s, h, w);
+        else
+            return this.dispatch(s, w, h);
+    },
+    
+    /*
+       Calculates a subtree base size. This is an utility function used by _getBaseSize_
+    */  
+    getTreeBaseSize: function(node, level, leaf) {
+        var size = this.getSize(node, true), baseHeight = 0, that = this;
+        if(leaf(level, node)) return size;
+        if(level === 0) return 0;
+        node.eachSubnode(function(elem) {
+            baseHeight += that.getTreeBaseSize(elem, level -1, leaf);
+        });
+        return (size > baseHeight? size : baseHeight) + this.config.subtreeOffset;
+    },
+
+
+    /*
+       getEdge
+       
+       Returns a Complex instance with the begin or end position of the edge to be plotted.
+
+       Parameters:
+
+       node - A <Graph.Node> that is connected to this edge.
+       type - Returns the begin or end edge position. Possible values are 'begin' or 'end'.
+
+       Returns:
+
+       A <Complex> number specifying the begin or end position.
+    */  
+    getEdge: function(node, type, s) {
+    	var $C = function(a, b) { 
+          return function(){
+            return node.pos.add(new Complex(a, b));
+          }; 
+        };
+        var dim = this.node;
+        var w = node.getData('width');
+        var h = node.getData('height');
+
+        if(type == 'begin') {
+            if(dim.align == "center") {
+                return this.dispatch(s, $C(0, h/2), $C(-w/2, 0),
+                                     $C(0, -h/2),$C(w/2, 0));
+            } else if(dim.align == "left") {
+                return this.dispatch(s, $C(0, h), $C(0, 0),
+                                     $C(0, 0), $C(w, 0));
+            } else if(dim.align == "right") {
+                return this.dispatch(s, $C(0, 0), $C(-w, 0),
+                                     $C(0, -h),$C(0, 0));
+            } else throw "align: not implemented";
+            
+            
+        } else if(type == 'end') {
+            if(dim.align == "center") {
+                return this.dispatch(s, $C(0, -h/2), $C(w/2, 0),
+                                     $C(0, h/2),  $C(-w/2, 0));
+            } else if(dim.align == "left") {
+                return this.dispatch(s, $C(0, 0), $C(w, 0),
+                                     $C(0, h), $C(0, 0));
+            } else if(dim.align == "right") {
+                return this.dispatch(s, $C(0, -h),$C(0, 0),
+                                     $C(0, 0), $C(-w, 0));
+            } else throw "align: not implemented";
+        }
+    },
+
+    /*
+       Adjusts the tree position due to canvas scaling or translation.
+    */  
+    getScaledTreePosition: function(node, scale) {
+        var dim = this.node;
+        var w = node.getData('width');
+        var h = node.getData('height');
+        var s = (this.config.multitree 
+        		&& ('$orn' in node.data) 
+        		&& node.data.$orn) || this.config.orientation;
+
+        var $C = function(a, b) { 
+          return function(){
+            return node.pos.add(new Complex(a, b)).$scale(1 - scale);
+          }; 
+        };
+        if(dim.align == "left") {
+            return this.dispatch(s, $C(0, h), $C(0, 0),
+                                 $C(0, 0), $C(w, 0));
+        } else if(dim.align == "center") {
+            return this.dispatch(s, $C(0, h / 2), $C(-w / 2, 0),
+                                 $C(0, -h / 2),$C(w / 2, 0));
+        } else if(dim.align == "right") {
+            return this.dispatch(s, $C(0, 0), $C(-w, 0),
+                                 $C(0, -h),$C(0, 0));
+        } else throw "align: not implemented";
+    },
+
+    /*
+       treeFitsInCanvas
+       
+       Returns a Boolean if the current subtree fits in canvas.
+
+       Parameters:
+
+       node - A <Graph.Node> which is the current root of the subtree.
+       canvas - The <Canvas> object.
+       level - The depth of the subtree to be considered.
+    */  
+    treeFitsInCanvas: function(node, canvas, level) {
+        var csize = canvas.getSize();
+        var s = (this.config.multitree 
+        		&& ('$orn' in node.data) 
+        		&& node.data.$orn) || this.config.orientation;
+
+        var size = this.dispatch(s, csize.width, csize.height);
+        var baseSize = this.getTreeBaseSize(node, level, function(level, node) { 
+          return level === 0 || !node.anySubnode();
+        });
+        return (baseSize < size);
+    }
+});
+
+/*
+  Class: ST.Plot
+  
+  Custom extension of <Graph.Plot>.
+
+  Extends:
+
+  All <Graph.Plot> methods
+  
+  See also:
+  
+  <Graph.Plot>
+
+*/
+$jit.ST.Plot = new Class({
+    
+    Implements: Graph.Plot,
+    
+    /*
+       Plots a subtree from the spacetree.
+    */
+    plotSubtree: function(node, opt, scale, animating) {
+        var viz = this.viz, canvas = viz.canvas, config = viz.config;
+        scale = Math.min(Math.max(0.001, scale), 1);
+        if(scale >= 0) {
+            node.drawn = false;     
+            var ctx = canvas.getCtx();
+            var diff = viz.geom.getScaledTreePosition(node, scale);
+            ctx.translate(diff.x, diff.y);
+            ctx.scale(scale, scale);
+        }
+        this.plotTree(node, $.merge(opt, {
+          'withLabels': true,
+          'hideLabels': !!scale,
+          'plotSubtree': function(n, ch) {
+            var root = config.multitree && !('$orn' in node.data);
+            var orns = root && node.getData('orns');
+            return !root || orns.indexOf(node.getData('orn')) > -1;
+          }
+        }), animating);
+        if(scale >= 0) node.drawn = true;
+    },   
+   
+    /*
+        Method: getAlignedPos
+        
+        Returns a *x, y* object with the position of the top/left corner of a <ST> node.
+        
+        Parameters:
+        
+        pos - (object) A <Graph.Node> position.
+        width - (number) The width of the node.
+        height - (number) The height of the node.
+        
+     */
+    getAlignedPos: function(pos, width, height) {
+        var nconfig = this.node;
+        var square, orn;
+        if(nconfig.align == "center") {
+            square = {
+                x: pos.x - width / 2,
+                y: pos.y - height / 2
+            };
+        } else if (nconfig.align == "left") {
+            orn = this.config.orientation;
+            if(orn == "bottom" || orn == "top") {
+                square = {
+                    x: pos.x - width / 2,
+                    y: pos.y
+                };
+            } else {
+                square = {
+                    x: pos.x,
+                    y: pos.y - height / 2
+                };
+            }
+        } else if(nconfig.align == "right") {
+            orn = this.config.orientation;
+            if(orn == "bottom" || orn == "top") {
+                square = {
+                    x: pos.x - width / 2,
+                    y: pos.y - height
+                };
+            } else {
+                square = {
+                    x: pos.x - width,
+                    y: pos.y - height / 2
+                };
+            }
+        } else throw "align: not implemented";
+        
+        return square;
+    },
+    
+    getOrientation: function(adj) {
+    	var config = this.config;
+    	var orn = config.orientation;
+
+    	if(config.multitree) {
+        	var nodeFrom = adj.nodeFrom;
+        	var nodeTo = adj.nodeTo;
+    		orn = (('$orn' in nodeFrom.data) 
+        		&& nodeFrom.data.$orn) 
+        		|| (('$orn' in nodeTo.data) 
+        		&& nodeTo.data.$orn);
+    	}
+
+    	return orn; 
+    }
+});
+
+/*
+  Class: ST.Label
+
+  Custom extension of <Graph.Label>. 
+  Contains custom <Graph.Label.SVG>, <Graph.Label.HTML> and <Graph.Label.Native> extensions.
+
+  Extends:
+
+  All <Graph.Label> methods and subclasses.
+
+  See also:
+
+  <Graph.Label>, <Graph.Label.Native>, <Graph.Label.HTML>, <Graph.Label.SVG>.
+ */ 
+$jit.ST.Label = {};
+
+/*
+   ST.Label.Native
+
+   Custom extension of <Graph.Label.Native>.
+
+   Extends:
+
+   All <Graph.Label.Native> methods
+
+   See also:
+
+   <Graph.Label.Native>
+*/
+$jit.ST.Label.Native = new Class({
+  Implements: Graph.Label.Native,
+
+  renderLabel: function(canvas, node, controller) {
+    var ctx = canvas.getCtx(),
+        coord = node.pos.getc(true),
+        width = node.getData('width'),
+        height = node.getData('height'),
+        pos = this.viz.fx.getAlignedPos(coord, width, height);
+    ctx.fillText(node.name, pos.x + width / 2, pos.y + height / 2);
+  }
+});
+
+$jit.ST.Label.DOM = new Class({
+  Implements: Graph.Label.DOM,
+
+  /* 
+      placeLabel
+
+      Overrides abstract method placeLabel in <Graph.Plot>.
+
+      Parameters:
+
+      tag - A DOM label element.
+      node - A <Graph.Node>.
+      controller - A configuration/controller object passed to the visualization.
+     
+    */
+    placeLabel: function(tag, node, controller) {
+        var pos = node.pos.getc(true), 
+            config = this.viz.config, 
+            dim = config.Node, 
+            canvas = this.viz.canvas,
+            w = node.getData('width'),
+            h = node.getData('height'),
+            radius = canvas.getSize(),
+            labelPos, orn;
+        
+        var ox = canvas.translateOffsetX,
+            oy = canvas.translateOffsetY,
+            sx = canvas.scaleOffsetX,
+            sy = canvas.scaleOffsetY,
+            posx = pos.x * sx + ox,
+            posy = pos.y * sy + oy;
+
+        if(dim.align == "center") {
+            labelPos= {
+                x: Math.round(posx - w / 2 + radius.width/2),
+                y: Math.round(posy - h / 2 + radius.height/2)
+            };
+        } else if (dim.align == "left") {
+            orn = config.orientation;
+            if(orn == "bottom" || orn == "top") {
+                labelPos= {
+                    x: Math.round(posx - w / 2 + radius.width/2),
+                    y: Math.round(posy + radius.height/2)
+                };
+            } else {
+                labelPos= {
+                    x: Math.round(posx + radius.width/2),
+                    y: Math.round(posy - h / 2 + radius.height/2)
+                };
+            }
+        } else if(dim.align == "right") {
+            orn = config.orientation;
+            if(orn == "bottom" || orn == "top") {
+                labelPos= {
+                    x: Math.round(posx - w / 2 + radius.width/2),
+                    y: Math.round(posy - h + radius.height/2)
+                };
+            } else {
+                labelPos= {
+                    x: Math.round(posx - w + radius.width/2),
+                    y: Math.round(posy - h / 2 + radius.height/2)
+                };
+            }
+        } else throw "align: not implemented";
+
+        var style = tag.style;
+        style.left = labelPos.x + 'px';
+        style.top  = labelPos.y + 'px';
+        style.display = this.fitsInCanvas(labelPos, canvas)? '' : 'none';
+        controller.onPlaceLabel(tag, node);
+    }
+});
+
+/*
+  ST.Label.SVG
+
+  Custom extension of <Graph.Label.SVG>.
+
+  Extends:
+
+  All <Graph.Label.SVG> methods
+
+  See also:
+
+  <Graph.Label.SVG>
+*/
+$jit.ST.Label.SVG = new Class({
+  Implements: [$jit.ST.Label.DOM, Graph.Label.SVG],
+
+  initialize: function(viz) {
+    this.viz = viz;
+  }
+});
+
+/*
+   ST.Label.HTML
+
+   Custom extension of <Graph.Label.HTML>.
+
+   Extends:
+
+   All <Graph.Label.HTML> methods.
+
+   See also:
+
+   <Graph.Label.HTML>
+
+*/
+$jit.ST.Label.HTML = new Class({
+  Implements: [$jit.ST.Label.DOM, Graph.Label.HTML],
+
+  initialize: function(viz) {
+    this.viz = viz;
+  }
+});
+
+
+/*
+  Class: ST.Plot.NodeTypes
+
+  This class contains a list of <Graph.Node> built-in types. 
+  Node types implemented are 'none', 'circle', 'rectangle', 'ellipse' and 'square'.
+
+  You can add your custom node types, customizing your visualization to the extreme.
+
+  Example:
+
+  (start code js)
+    ST.Plot.NodeTypes.implement({
+      'mySpecialType': {
+        'render': function(node, canvas) {
+          //print your custom node to canvas
+        },
+        //optional
+        'contains': function(node, pos) {
+          //return true if pos is inside the node or false otherwise
+        }
+      }
+    });
+  (end code)
+
+*/
+$jit.ST.Plot.NodeTypes = new Class({
+  'none': {
+    'render': $.empty,
+    'contains': $.lambda(false)
+  },
+  'circle': {
+    'render': function(node, canvas) {
+      var dim  = node.getData('dim'),
+          pos = this.getAlignedPos(node.pos.getc(true), dim, dim),
+          dim2 = dim/2;
+      this.nodeHelper.circle.render('fill', {x:pos.x+dim2, y:pos.y+dim2}, dim2, canvas);
+    },
+    'contains': function(node, pos) {
+      var dim  = node.getData('dim'),
+          npos = this.getAlignedPos(node.pos.getc(true), dim, dim),
+          dim2 = dim/2;
+      this.nodeHelper.circle.contains({x:npos.x+dim2, y:npos.y+dim2}, pos, dim2);
+    }
+  },
+  'square': {
+    'render': function(node, canvas) {
+      var dim  = node.getData('dim'),
+          dim2 = dim/2,
+          pos = this.getAlignedPos(node.pos.getc(true), dim, dim);
+      this.nodeHelper.square.render('fill', {x:pos.x+dim2, y:pos.y+dim2}, dim2, canvas);
+    },
+    'contains': function(node, pos) {
+      var dim  = node.getData('dim'),
+          npos = this.getAlignedPos(node.pos.getc(true), dim, dim),
+          dim2 = dim/2;
+      this.nodeHelper.square.contains({x:npos.x+dim2, y:npos.y+dim2}, pos, dim2);
+    }
+  },
+  'ellipse': {
+    'render': function(node, canvas) {
+      var width = node.getData('width'),
+          height = node.getData('height'),
+          pos = this.getAlignedPos(node.pos.getc(true), width, height);
+      this.nodeHelper.ellipse.render('fill', {x:pos.x+width/2, y:pos.y+height/2}, width, height, canvas);
+    },
+    'contains': function(node, pos) {
+      var width = node.getData('width'),
+          height = node.getData('height'),
+          npos = this.getAlignedPos(node.pos.getc(true), width, height);
+      this.nodeHelper.ellipse.contains({x:npos.x+width/2, y:npos.y+height/2}, pos, width, height);
+    }
+  },
+  'rectangle': {
+    'render': function(node, canvas) {
+      var width = node.getData('width'),
+          height = node.getData('height'),
+          pos = this.getAlignedPos(node.pos.getc(true), width, height);
+      this.nodeHelper.rectangle.render('fill', {x:pos.x+width/2, y:pos.y+height/2}, width, height, canvas);
+    },
+    'contains': function(node, pos) {
+      var width = node.getData('width'),
+          height = node.getData('height'),
+          npos = this.getAlignedPos(node.pos.getc(true), width, height);
+      this.nodeHelper.rectangle.contains({x:npos.x+width/2, y:npos.y+height/2}, pos, width, height);
+    }
+  }
+});
+
+/*
+  Class: ST.Plot.EdgeTypes
+
+  This class contains a list of <Graph.Adjacence> built-in types. 
+  Edge types implemented are 'none', 'line', 'arrow', 'quadratic:begin', 'quadratic:end', 'bezier'.
+
+  You can add your custom edge types, customizing your visualization to the extreme.
+
+  Example:
+
+  (start code js)
+    ST.Plot.EdgeTypes.implement({
+      'mySpecialType': {
+        'render': function(adj, canvas) {
+          //print your custom edge to canvas
+        },
+        //optional
+        'contains': function(adj, pos) {
+          //return true if pos is inside the arc or false otherwise
+        }
+      }
+    });
+  (end code)
+
+*/
+$jit.ST.Plot.EdgeTypes = new Class({
+    'none': $.empty,
+    'line': {
+      'render': function(adj, canvas) {
+        var orn = this.getOrientation(adj),
+            nodeFrom = adj.nodeFrom, 
+            nodeTo = adj.nodeTo,
+            rel = nodeFrom._depth < nodeTo._depth,
+            from = this.viz.geom.getEdge(rel? nodeFrom:nodeTo, 'begin', orn),
+            to =  this.viz.geom.getEdge(rel? nodeTo:nodeFrom, 'end', orn);
+        this.edgeHelper.line.render(from, to, canvas);
+      },
+      'contains': function(adj, pos) {
+        var orn = this.getOrientation(adj),
+            nodeFrom = adj.nodeFrom, 
+            nodeTo = adj.nodeTo,
+            rel = nodeFrom._depth < nodeTo._depth,
+            from = this.viz.geom.getEdge(rel? nodeFrom:nodeTo, 'begin', orn),
+            to =  this.viz.geom.getEdge(rel? nodeTo:nodeFrom, 'end', orn);
+        return this.edgeHelper.line.contains(from, to, pos, this.edge.epsilon);
+      }
+    },
+     'arrow': {
+       'render': function(adj, canvas) {
+         var orn = this.getOrientation(adj),
+             node = adj.nodeFrom, 
+             child = adj.nodeTo,
+             dim = adj.getData('dim'),
+             from = this.viz.geom.getEdge(node, 'begin', orn),
+             to = this.viz.geom.getEdge(child, 'end', orn),
+             direction = adj.data.$direction,
+             inv = (direction && direction.length>1 && direction[0] != node.id);
+         this.edgeHelper.arrow.render(from, to, dim, inv, canvas);
+       },
+       'contains': function(adj, pos) {
+         var orn = this.getOrientation(adj),
+             nodeFrom = adj.nodeFrom, 
+             nodeTo = adj.nodeTo,
+             rel = nodeFrom._depth < nodeTo._depth,
+             from = this.viz.geom.getEdge(rel? nodeFrom:nodeTo, 'begin', orn),
+             to =  this.viz.geom.getEdge(rel? nodeTo:nodeFrom, 'end', orn);
+         return this.edgeHelper.arrow.contains(from, to, pos, this.edge.epsilon);
+       }
+     },
+    'quadratic:begin': {
+       'render': function(adj, canvas) {
+          var orn = this.getOrientation(adj);
+          var nodeFrom = adj.nodeFrom, 
+              nodeTo = adj.nodeTo,
+              rel = nodeFrom._depth < nodeTo._depth,
+              begin = this.viz.geom.getEdge(rel? nodeFrom:nodeTo, 'begin', orn),
+              end =  this.viz.geom.getEdge(rel? nodeTo:nodeFrom, 'end', orn),
+              dim = adj.getData('dim'),
+              ctx = canvas.getCtx();
+          ctx.beginPath();
+          ctx.moveTo(begin.x, begin.y);
+          switch(orn) {
+            case "left":
+              ctx.quadraticCurveTo(begin.x + dim, begin.y, end.x, end.y);
+              break;
+            case "right":
+              ctx.quadraticCurveTo(begin.x - dim, begin.y, end.x, end.y);
+              break;
+            case "top":
+              ctx.quadraticCurveTo(begin.x, begin.y + dim, end.x, end.y);
+              break;
+            case "bottom":
+              ctx.quadraticCurveTo(begin.x, begin.y - dim, end.x, end.y);
+              break;
+          }
+          ctx.stroke();
+        }
+     },
+    'quadratic:end': {
+       'render': function(adj, canvas) {
+          var orn = this.getOrientation(adj);
+          var nodeFrom = adj.nodeFrom, 
+              nodeTo = adj.nodeTo,
+              rel = nodeFrom._depth < nodeTo._depth,
+              begin = this.viz.geom.getEdge(rel? nodeFrom:nodeTo, 'begin', orn),
+              end =  this.viz.geom.getEdge(rel? nodeTo:nodeFrom, 'end', orn),
+              dim = adj.getData('dim'),
+              ctx = canvas.getCtx();
+          ctx.beginPath();
+          ctx.moveTo(begin.x, begin.y);
+          switch(orn) {
+            case "left":
+              ctx.quadraticCurveTo(end.x - dim, end.y, end.x, end.y);
+              break;
+            case "right":
+              ctx.quadraticCurveTo(end.x + dim, end.y, end.x, end.y);
+              break;
+            case "top":
+              ctx.quadraticCurveTo(end.x, end.y - dim, end.x, end.y);
+              break;
+            case "bottom":
+              ctx.quadraticCurveTo(end.x, end.y + dim, end.x, end.y);
+              break;
+          }
+          ctx.stroke();
+       }
+     },
+    'bezier': {
+       'render': function(adj, canvas) {
+         var orn = this.getOrientation(adj),
+             nodeFrom = adj.nodeFrom, 
+             nodeTo = adj.nodeTo,
+             rel = nodeFrom._depth < nodeTo._depth,
+             begin = this.viz.geom.getEdge(rel? nodeFrom:nodeTo, 'begin', orn),
+             end =  this.viz.geom.getEdge(rel? nodeTo:nodeFrom, 'end', orn),
+             dim = adj.getData('dim'),
+             ctx = canvas.getCtx();
+         ctx.beginPath();
+         ctx.moveTo(begin.x, begin.y);
+         switch(orn) {
+           case "left":
+             ctx.bezierCurveTo(begin.x + dim, begin.y, end.x - dim, end.y, end.x, end.y);
+             break;
+           case "right":
+             ctx.bezierCurveTo(begin.x - dim, begin.y, end.x + dim, end.y, end.x, end.y);
+             break;
+           case "top":
+             ctx.bezierCurveTo(begin.x, begin.y + dim, end.x, end.y - dim, end.x, end.y);
+             break;
+           case "bottom":
+             ctx.bezierCurveTo(begin.x, begin.y - dim, end.x, end.y + dim, end.x, end.y);
+             break;
+         }
+         ctx.stroke();
+       }
+    }
+});
+
+
+
+/*
+ * File: AreaChart.js
+ *
+*/
+
+$jit.ST.Plot.NodeTypes.implement({
+  'areachart-stacked' : {
+    'render' : function(node, canvas) {
+      var pos = node.pos.getc(true), 
+          width = node.getData('width'),
+          height = node.getData('height'),
+          algnPos = this.getAlignedPos(pos, width, height),
+          x = algnPos.x, y = algnPos.y,
+          stringArray = node.getData('stringArray'),
+          dimArray = node.getData('dimArray'),
+          valArray = node.getData('valueArray'),
+          valLeft = $.reduce(valArray, function(x, y) { return x + y[0]; }, 0),
+          valRight = $.reduce(valArray, function(x, y) { return x + y[1]; }, 0),
+          colorArray = node.getData('colorArray'),
+          colorLength = colorArray.length,
+          config = node.getData('config'),
+          gradient = node.getData('gradient'),
+          showLabels = config.showLabels,
+          aggregates = config.showAggregates,
+          label = config.Label,
+          prev = node.getData('prev');
+
+      var ctx = canvas.getCtx(), border = node.getData('border');
+      if (colorArray && dimArray && stringArray) {
+        for (var i=0, l=dimArray.length, acumLeft=0, acumRight=0, valAcum=0; i<l; i++) {
+          ctx.fillStyle = ctx.strokeStyle = colorArray[i % colorLength];
+          ctx.save();
+          if(gradient && (dimArray[i][0] > 0 || dimArray[i][1] > 0)) {
+            var h1 = acumLeft + dimArray[i][0],
+                h2 = acumRight + dimArray[i][1],
+                alpha = Math.atan((h2 - h1) / width),
+                delta = 55;
+            var linear = ctx.createLinearGradient(x + width/2, 
+                y - (h1 + h2)/2,
+                x + width/2 + delta * Math.sin(alpha),
+                y - (h1 + h2)/2 + delta * Math.cos(alpha));
+            var color = $.rgbToHex($.map($.hexToRgb(colorArray[i % colorLength].slice(1)), 
+                function(v) { return (v * 0.85) >> 0; }));
+            linear.addColorStop(0, colorArray[i % colorLength]);
+            linear.addColorStop(1, color);
+            ctx.fillStyle = linear;
+          }
+          ctx.beginPath();
+          ctx.moveTo(x, y - acumLeft);
+          ctx.lineTo(x + width, y - acumRight);
+          ctx.lineTo(x + width, y - acumRight - dimArray[i][1]);
+          ctx.lineTo(x, y - acumLeft - dimArray[i][0]);
+          ctx.lineTo(x, y - acumLeft);
+          ctx.fill();
+          ctx.restore();
+          if(border) {
+            var strong = border.name == stringArray[i];
+            var perc = strong? 0.7 : 0.8;
+            var color = $.rgbToHex($.map($.hexToRgb(colorArray[i % colorLength].slice(1)), 
+                function(v) { return (v * perc) >> 0; }));
+            ctx.strokeStyle = color;
+            ctx.lineWidth = strong? 4 : 1;
+            ctx.save();
+            ctx.beginPath();
+            if(border.index === 0) {
+              ctx.moveTo(x, y - acumLeft);
+              ctx.lineTo(x, y - acumLeft - dimArray[i][0]);
+            } else {
+              ctx.moveTo(x + width, y - acumRight);
+              ctx.lineTo(x + width, y - acumRight - dimArray[i][1]);
+            }
+            ctx.stroke();
+            ctx.restore();
+          }
+          acumLeft += (dimArray[i][0] || 0);
+          acumRight += (dimArray[i][1] || 0);
+          
+          if(dimArray[i][0] > 0)
+            valAcum += (valArray[i][0] || 0);
+        }
+        if(prev && label.type == 'Native') {
+          ctx.save();
+          ctx.beginPath();
+          ctx.fillStyle = ctx.strokeStyle = label.color;
+          ctx.font = label.style + ' ' + label.size + 'px ' + label.family;
+          ctx.textAlign = 'center';
+          ctx.textBaseline = 'middle';
+          var aggValue = aggregates(node.name, valLeft, valRight, node, valAcum);
+          if(aggValue !== false) {
+            ctx.fillText(aggValue !== true? aggValue : valAcum, x, y - acumLeft - config.labelOffset - label.size/2, width);
+          }
+          if(showLabels(node.name, valLeft, valRight, node)) {
+            ctx.fillText(node.name, x, y + label.size/2 + config.labelOffset);
+          }
+          ctx.restore();
+        }
+      }
+    },
+    'contains': function(node, mpos) {
+      var pos = node.pos.getc(true), 
+          width = node.getData('width'),
+          height = node.getData('height'),
+          algnPos = this.getAlignedPos(pos, width, height),
+          x = algnPos.x, y = algnPos.y,
+          dimArray = node.getData('dimArray'),
+          rx = mpos.x - x;
+      //bounding box check
+      if(mpos.x < x || mpos.x > x + width
+        || mpos.y > y || mpos.y < y - height) {
+        return false;
+      }
+      //deep check
+      for(var i=0, l=dimArray.length, lAcum=y, rAcum=y; i<l; i++) {
+        var dimi = dimArray[i];
+        lAcum -= dimi[0];
+        rAcum -= dimi[1];
+        var intersec = lAcum + (rAcum - lAcum) * rx / width;
+        if(mpos.y >= intersec) {
+          var index = +(rx > width/2);
+          return {
+            'name': node.getData('stringArray')[i],
+            'color': node.getData('colorArray')[i],
+            'value': node.getData('valueArray')[i][index],
+            'index': index
+          };
+        }
+      }
+      return false;
+    }
+  }
+});
+
+/*
+  Class: AreaChart
+  
+  A visualization that displays stacked area charts.
+  
+  Constructor Options:
+  
+  See <Options.AreaChart>.
+
+*/
+$jit.AreaChart = new Class({
+  st: null,
+  colors: ["#416D9C", "#70A35E", "#EBB056", "#C74243", "#83548B", "#909291", "#557EAA"],
+  selected: {},
+  busy: false,
+  
+  initialize: function(opt) {
+    this.controller = this.config = 
+      $.merge(Options("Canvas", "Margin", "Label", "AreaChart"), {
+        Label: { type: 'Native' }
+      }, opt);
+    //set functions for showLabels and showAggregates
+    var showLabels = this.config.showLabels,
+        typeLabels = $.type(showLabels),
+        showAggregates = this.config.showAggregates,
+        typeAggregates = $.type(showAggregates);
+    this.config.showLabels = typeLabels == 'function'? showLabels : $.lambda(showLabels);
+    this.config.showAggregates = typeAggregates == 'function'? showAggregates : $.lambda(showAggregates);
+    
+    this.initializeViz();
+  },
+  
+  initializeViz: function() {
+    var config = this.config,
+        that = this,
+        nodeType = config.type.split(":")[0],
+        nodeLabels = {};
+
+    var delegate = new $jit.ST({
+      injectInto: config.injectInto,
+      width: config.width,
+      height: config.height,
+      orientation: "bottom",
+      levelDistance: 0,
+      siblingOffset: 0,
+      subtreeOffset: 0,
+      withLabels: config.Label.type != 'Native',
+      useCanvas: config.useCanvas,
+      Label: {
+        type: config.Label.type
+      },
+      Node: {
+        overridable: true,
+        type: 'areachart-' + nodeType,
+        align: 'left',
+        width: 1,
+        height: 1
+      },
+      Edge: {
+        type: 'none'
+      },
+      Tips: {
+        enable: config.Tips.enable,
+        type: 'Native',
+        force: true,
+        onShow: function(tip, node, contains) {
+          var elem = contains;
+          config.Tips.onShow(tip, elem, node);
+        }
+      },
+      Events: {
+        enable: true,
+        type: 'Native',
+        onClick: function(node, eventInfo, evt) {
+          if(!config.filterOnClick && !config.Events.enable) return;
+          var elem = eventInfo.getContains();
+          if(elem) config.filterOnClick && that.filter(elem.name);
+          config.Events.enable && config.Events.onClick(elem, eventInfo, evt);
+        },
+        onRightClick: function(node, eventInfo, evt) {
+          if(!config.restoreOnRightClick) return;
+          that.restore();
+        },
+        onMouseMove: function(node, eventInfo, evt) {
+          if(!config.selectOnHover) return;
+          if(node) {
+            var elem = eventInfo.getContains();
+            that.select(node.id, elem.name, elem.index);
+          } else {
+            that.select(false, false, false);
+          }
+        }
+      },
+      onCreateLabel: function(domElement, node) {
+        var labelConf = config.Label,
+            valueArray = node.getData('valueArray'),
+            acumLeft = $.reduce(valueArray, function(x, y) { return x + y[0]; }, 0),
+            acumRight = $.reduce(valueArray, function(x, y) { return x + y[1]; }, 0);
+        if(node.getData('prev')) {
+          var nlbs = {
+            wrapper: document.createElement('div'),
+            aggregate: document.createElement('div'),
+            label: document.createElement('div')
+          };
+          var wrapper = nlbs.wrapper,
+              label = nlbs.label,
+              aggregate = nlbs.aggregate,
+              wrapperStyle = wrapper.style,
+              labelStyle = label.style,
+              aggregateStyle = aggregate.style;
+          //store node labels
+          nodeLabels[node.id] = nlbs;
+          //append labels
+          wrapper.appendChild(label);
+          wrapper.appendChild(aggregate);
+          if(!config.showLabels(node.name, acumLeft, acumRight, node)) {
+            label.style.display = 'none';
+          }
+          if(!config.showAggregates(node.name, acumLeft, acumRight, node)) {
+            aggregate.style.display = 'none';
+          }
+          wrapperStyle.position = 'relative';
+          wrapperStyle.overflow = 'visible';
+          wrapperStyle.fontSize = labelConf.size + 'px';
+          wrapperStyle.fontFamily = labelConf.family;
+          wrapperStyle.color = labelConf.color;
+          wrapperStyle.textAlign = 'center';
+          aggregateStyle.position = labelStyle.position = 'absolute';
+          
+          domElement.style.width = node.getData('width') + 'px';
+          domElement.style.height = node.getData('height') + 'px';
+          label.innerHTML = node.name;
+          
+          domElement.appendChild(wrapper);
+        }
+      },
+      onPlaceLabel: function(domElement, node) {
+        if(!node.getData('prev')) return;
+        var labels = nodeLabels[node.id],
+            wrapperStyle = labels.wrapper.style,
+            labelStyle = labels.label.style,
+            aggregateStyle = labels.aggregate.style,
+            width = node.getData('width'),
+            height = node.getData('height'),
+            dimArray = node.getData('dimArray'),
+            valArray = node.getData('valueArray'),
+            acumLeft = $.reduce(valArray, function(x, y) { return x + y[0]; }, 0),
+            acumRight = $.reduce(valArray, function(x, y) { return x + y[1]; }, 0),
+            font = parseInt(wrapperStyle.fontSize, 10),
+            domStyle = domElement.style;
+        
+        if(dimArray && valArray) {
+          if(config.showLabels(node.name, acumLeft, acumRight, node)) {
+            labelStyle.display = '';
+          } else {
+            labelStyle.display = 'none';
+          }
+          var aggValue = config.showAggregates(node.name, acumLeft, acumRight, node);
+          if(aggValue !== false) {
+            aggregateStyle.display = '';
+          } else {
+            aggregateStyle.display = 'none';
+          }
+          wrapperStyle.width = aggregateStyle.width = labelStyle.width = domElement.style.width = width + 'px';
+          aggregateStyle.left = labelStyle.left = -width/2 + 'px';
+          for(var i=0, l=valArray.length, acum=0, leftAcum=0; i<l; i++) {
+            if(dimArray[i][0] > 0) {
+              acum+= valArray[i][0];
+              leftAcum+= dimArray[i][0];
+            }
+          }
+          aggregateStyle.top = (-font - config.labelOffset) + 'px';
+          labelStyle.top = (config.labelOffset + leftAcum) + 'px';
+          domElement.style.top = parseInt(domElement.style.top, 10) - leftAcum + 'px';
+          domElement.style.height = wrapperStyle.height = leftAcum + 'px';
+          labels.aggregate.innerHTML = aggValue !== true? aggValue : acum;
+        }
+      }
+    });
+    
+    var size = delegate.canvas.getSize(),
+        margin = config.Margin;
+    delegate.config.offsetY = -size.height/2 + margin.bottom 
+      + (config.showLabels && (config.labelOffset + config.Label.size));
+    delegate.config.offsetX = (margin.right - margin.left)/2;
+    this.delegate = delegate;
+    this.canvas = this.delegate.canvas;
+  },
+  
+ /*
+  Method: loadJSON
+ 
+  Loads JSON data into the visualization. 
+  
+  Parameters:
+  
+  json - The JSON data format. This format is described in <http://blog.thejit.org/2010/04/24/new-javascript-infovis-toolkit-visualizations/#json-data-format>.
+  
+  Example:
+  (start code js)
+  var areaChart = new $jit.AreaChart(options);
+  areaChart.loadJSON(json);
+  (end code)
+ */  
+  loadJSON: function(json) {
+    var prefix = $.time(), 
+        ch = [], 
+        delegate = this.delegate,
+        name = $.splat(json.label), 
+        color = $.splat(json.color || this.colors),
+        config = this.config,
+        gradient = !!config.type.split(":")[1],
+        animate = config.animate;
+    
+    for(var i=0, values=json.values, l=values.length; i<l-1; i++) {
+      var val = values[i], prev = values[i-1], next = values[i+1];
+      var valLeft = $.splat(values[i].values), valRight = $.splat(values[i+1].values);
+      var valArray = $.zip(valLeft, valRight);
+      var acumLeft = 0, acumRight = 0;
+      ch.push({
+        'id': prefix + val.label,
+        'name': val.label,
+        'data': {
+          'value': valArray,
+          '$valueArray': valArray,
+          '$colorArray': color,
+          '$stringArray': name,
+          '$next': next.label,
+          '$prev': prev? prev.label:false,
+          '$config': config,
+          '$gradient': gradient
+        },
+        'children': []
+      });
+    }
+    var root = {
+      'id': prefix + '$root',
+      'name': '',
+      'data': {
+        '$type': 'none',
+        '$width': 1,
+        '$height': 1
+      },
+      'children': ch
+    };
+    delegate.loadJSON(root);
+    
+    this.normalizeDims();
+    delegate.compute();
+    delegate.select(delegate.root);
+    if(animate) {
+      delegate.fx.animate({
+        modes: ['node-property:height:dimArray'],
+        duration:1500
+      });
+    }
+  },
+  
+ /*
+  Method: updateJSON
+ 
+  Use this method when updating values for the current JSON data. If the items specified by the JSON data already exist in the graph then their values will be updated.
+  
+  Parameters:
+  
+  json - (object) JSON data to be updated. The JSON format corresponds to the one described in <AreaChart.loadJSON>.
+  onComplete - (object) A callback object to be called when the animation transition when updating the data end.
+  
+  Example:
+  
+  (start code js)
+  areaChart.updateJSON(json, {
+    onComplete: function() {
+      alert('update complete!');
+    }
+  });
+  (end code)
+ */  
+  updateJSON: function(json, onComplete) {
+    if(this.busy) return;
+    this.busy = true;
+    
+    var delegate = this.delegate,
+        graph = delegate.graph,
+        labels = json.label && $.splat(json.label),
+        values = json.values,
+        animate = this.config.animate,
+        that = this,
+        hashValues = {};
+
+    //convert the whole thing into a hash
+    for (var i = 0, l = values.length; i < l; i++) {
+      hashValues[values[i].label] = values[i];
+    }
+  
+    graph.eachNode(function(n) {
+      var v = hashValues[n.name],
+          stringArray = n.getData('stringArray'),
+          valArray = n.getData('valueArray'),
+          next = n.getData('next');
+      
+      if (v) {
+        v.values = $.splat(v.values);
+        $.each(valArray, function(a, i) {
+          a[0] = v.values[i];
+          if(labels) stringArray[i] = labels[i];
+        });
+        n.setData('valueArray', valArray);
+      }
+     
+      if(next) {
+        v = hashValues[next];
+        if(v) {
+          $.each(valArray, function(a, i) {
+            a[1] = v.values[i];
+          });
+        }
+      }
+    });
+    this.normalizeDims();
+    delegate.compute();
+    delegate.select(delegate.root);
+    if(animate) {
+      delegate.fx.animate({
+        modes: ['node-property:height:dimArray'],
+        duration:1500,
+        onComplete: function() {
+          that.busy = false;
+          onComplete && onComplete.onComplete();
+        }
+      });
+    }
+  },
+  
+/*
+  Method: filter
+ 
+  Filter selected stacks, collapsing all other stacks. You can filter multiple stacks at the same time.
+  
+  Parameters:
+  
+  filters - (array) An array of strings with the name of the stacks to be filtered.
+  callback - (object) An object with an *onComplete* callback method. 
+  
+  Example:
+  
+  (start code js)
+  areaChart.filter(['label A', 'label C'], {
+      onComplete: function() {
+          console.log('done!');
+      }
+  });
+  (end code)
+  
+  See also:
+  
+  <AreaChart.restore>.
+ */  
+  filter: function(filters, callback) {
+    if(this.busy) return;
+    this.busy = true;
+    if(this.config.Tips.enable) this.delegate.tips.hide();
+    this.select(false, false, false);
+    var args = $.splat(filters);
+    var rt = this.delegate.graph.getNode(this.delegate.root);
+    var that = this;
+    this.normalizeDims();
+    rt.eachAdjacency(function(adj) {
+      var n = adj.nodeTo, 
+          dimArray = n.getData('dimArray', 'end'),
+          stringArray = n.getData('stringArray');
+      n.setData('dimArray', $.map(dimArray, function(d, i) {
+        return ($.indexOf(args, stringArray[i]) > -1)? d:[0, 0];
+      }), 'end');
+    });
+    this.delegate.fx.animate({
+      modes: ['node-property:dimArray'],
+      duration:1500,
+      onComplete: function() {
+        that.busy = false;
+        callback && callback.onComplete();
+      }
+    });
+  },
+  
+  /*
+  Method: restore
+ 
+  Sets all stacks that could have been filtered visible.
+  
+  Example:
+  
+  (start code js)
+  areaChart.restore();
+  (end code)
+  
+  See also:
+  
+  <AreaChart.filter>.
+ */  
+  restore: function(callback) {
+    if(this.busy) return;
+    this.busy = true;
+    if(this.config.Tips.enable) this.delegate.tips.hide();
+    this.select(false, false, false);
+    this.normalizeDims();
+    var that = this;
+    this.delegate.fx.animate({
+      modes: ['node-property:height:dimArray'],
+      duration:1500,
+      onComplete: function() {
+        that.busy = false;
+        callback && callback.onComplete();
+      }
+    });
+  },
+  //adds the little brown bar when hovering the node
+  select: function(id, name, index) {
+    if(!this.config.selectOnHover) return;
+    var s = this.selected;
+    if(s.id != id || s.name != name 
+        || s.index != index) {
+      s.id = id;
+      s.name = name;
+      s.index = index;
+      this.delegate.graph.eachNode(function(n) {
+        n.setData('border', false);
+      });
+      if(id) {
+        var n = this.delegate.graph.getNode(id);
+        n.setData('border', s);
+        var link = index === 0? 'prev':'next';
+        link = n.getData(link);
+        if(link) {
+          n = this.delegate.graph.getByName(link);
+          if(n) {
+            n.setData('border', {
+              name: name,
+              index: 1-index
+            });
+          }
+        }
+      }
+      this.delegate.plot();
+    }
+  },
+  
+  /*
+    Method: getLegend
+   
+    Returns an object containing as keys the legend names and as values hex strings with color values.
+    
+    Example:
+    
+    (start code js)
+    var legend = areaChart.getLegend();
+    (end code)
+ */  
+  getLegend: function() {
+    var legend = {};
+    var n;
+    this.delegate.graph.getNode(this.delegate.root).eachAdjacency(function(adj) {
+      n = adj.nodeTo;
+    });
+    var colors = n.getData('colorArray'),
+        len = colors.length;
+    $.each(n.getData('stringArray'), function(s, i) {
+      legend[s] = colors[i % len];
+    });
+    return legend;
+  },
+  
+  /*
+    Method: getMaxValue
+   
+    Returns the maximum accumulated value for the stacks. This method is used for normalizing the graph heights according to the canvas height.
+    
+    Example:
+    
+    (start code js)
+    var ans = areaChart.getMaxValue();
+    (end code)
+    
+    In some cases it could be useful to override this method to normalize heights for a group of AreaCharts, like when doing small multiples.
+    
+    Example:
+    
+    (start code js)
+    //will return 100 for all AreaChart instances,
+    //displaying all of them with the same scale
+    $jit.AreaChart.implement({
+      'getMaxValue': function() {
+        return 100;
+      }
+    });
+    (end code)
+    
+*/  
+  getMaxValue: function() {
+    var maxValue = 0;
+    this.delegate.graph.eachNode(function(n) {
+      var valArray = n.getData('valueArray'),
+          acumLeft = 0, acumRight = 0;
+      $.each(valArray, function(v) { 
+        acumLeft += +v[0];
+        acumRight += +v[1];
+      });
+      var acum = acumRight>acumLeft? acumRight:acumLeft;
+      maxValue = maxValue>acum? maxValue:acum;
+    });
+    return maxValue;
+  },
+  
+  normalizeDims: function() {
+    //number of elements
+    var root = this.delegate.graph.getNode(this.delegate.root), l=0;
+    root.eachAdjacency(function() {
+      l++;
+    });
+    var maxValue = this.getMaxValue() || 1,
+        size = this.delegate.canvas.getSize(),
+        config = this.config,
+        margin = config.Margin,
+        labelOffset = config.labelOffset + config.Label.size,
+        fixedDim = (size.width - (margin.left + margin.right)) / l,
+        animate = config.animate,
+        height = size.height - (margin.top + margin.bottom) - (config.showAggregates && labelOffset) 
+          - (config.showLabels && labelOffset);
+    this.delegate.graph.eachNode(function(n) {
+      var acumLeft = 0, acumRight = 0, animateValue = [];
+      $.each(n.getData('valueArray'), function(v) {
+        acumLeft += +v[0];
+        acumRight += +v[1];
+        animateValue.push([0, 0]);
+      });
+      var acum = acumRight>acumLeft? acumRight:acumLeft;
+      n.setData('width', fixedDim);
+      if(animate) {
+        n.setData('height', acum * height / maxValue, 'end');
+        n.setData('dimArray', $.map(n.getData('valueArray'), function(n) { 
+          return [n[0] * height / maxValue, n[1] * height / maxValue]; 
+        }), 'end');
+        var dimArray = n.getData('dimArray');
+        if(!dimArray) {
+          n.setData('dimArray', animateValue);
+        }
+      } else {
+        n.setData('height', acum * height / maxValue);
+        n.setData('dimArray', $.map(n.getData('valueArray'), function(n) { 
+          return [n[0] * height / maxValue, n[1] * height / maxValue]; 
+        }));
+      }
+    });
+  }
+});
+
+
+/*
+ * File: Options.BarChart.js
+ *
+*/
+
+/*
+  Object: Options.BarChart
+  
+  <BarChart> options. 
+  Other options included in the BarChart are <Options.Canvas>, <Options.Label>, <Options.Margin>, <Options.Tips> and <Options.Events>.
+  
+  Syntax:
+  
+  (start code js)
+
+  Options.BarChart = {
+    animate: true,
+    labelOffset: 3,
+    barsOffset: 0,
+    type: 'stacked',
+    hoveredColor: '#9fd4ff',
+    orientation: 'horizontal',
+    showAggregates: true,
+    showLabels: true
+  };
+  
+  (end code)
+  
+  Example:
+  
+  (start code js)
+
+  var barChart = new $jit.BarChart({
+    animate: true,
+    barsOffset: 10,
+    type: 'stacked:gradient'
+  });
+  
+  (end code)
+
+  Parameters:
+  
+  animate - (boolean) Default's *true*. Whether to add animated transitions when filtering/restoring stacks.
+  offset - (number) Default's *25*. Adds margin between the visualization and the canvas.
+  labelOffset - (number) Default's *3*. Adds margin between the label and the default place where it should be drawn.
+  barsOffset - (number) Default's *0*. Separation between bars.
+  type - (string) Default's *'stacked'*. Stack or grouped styles. Posible values are 'stacked', 'grouped', 'stacked:gradient', 'grouped:gradient' to add gradients.
+  hoveredColor - (boolean|string) Default's *'#9fd4ff'*. Sets the selected color for a hovered bar stack.
+  orientation - (string) Default's 'horizontal'. Sets the direction of the bars. Possible options are 'vertical' or 'horizontal'.
+  showAggregates - (boolean, function) Default's *true*. Display the sum the values of each bar. Can also be a function that returns *true* or *false* to display the value of the bar or not. That same function can also return a string with the formatted data to be added.
+  showLabels - (boolean, function) Default's *true*. Display the name of the slots. Can also be a function that returns *true* or *false* for each bar to decide whether to show the label or not.
+  
+*/
+
+Options.BarChart = {
+  $extend: true,
+  
+  animate: true,
+  type: 'stacked', //stacked, grouped, : gradient
+  labelOffset: 3, //label offset
+  barsOffset: 0, //distance between bars
+  hoveredColor: '#9fd4ff',
+  orientation: 'horizontal',
+  showAggregates: true,
+  showLabels: true,
+  Tips: {
+    enable: false,
+    onShow: $.empty,
+    onHide: $.empty
+  },
+  Events: {
+    enable: false,
+    onClick: $.empty
+  }
+};
+
+/*
+ * File: BarChart.js
+ *
+*/
+
+$jit.ST.Plot.NodeTypes.implement({
+  'barchart-stacked' : {
+    'render' : function(node, canvas) {
+      var pos = node.pos.getc(true), 
+          width = node.getData('width'),
+          height = node.getData('height'),
+          algnPos = this.getAlignedPos(pos, width, height),
+          x = algnPos.x, y = algnPos.y,
+          dimArray = node.getData('dimArray'),
+          valueArray = node.getData('valueArray'),
+          colorArray = node.getData('colorArray'),
+          colorLength = colorArray.length,
+          stringArray = node.getData('stringArray');
+
+      var ctx = canvas.getCtx(),
+          opt = {},
+          border = node.getData('border'),
+          gradient = node.getData('gradient'),
+          config = node.getData('config'),
+          horz = config.orientation == 'horizontal',
+          aggregates = config.showAggregates,
+          showLabels = config.showLabels,
+          label = config.Label;
+      
+      if (colorArray && dimArray && stringArray) {
+        for (var i=0, l=dimArray.length, acum=0, valAcum=0; i<l; i++) {
+          ctx.fillStyle = ctx.strokeStyle = colorArray[i % colorLength];
+          if(gradient) {
+            var linear;
+            if(horz) {
+              linear = ctx.createLinearGradient(x + acum + dimArray[i]/2, y, 
+                  x + acum + dimArray[i]/2, y + height);
+            } else {
+              linear = ctx.createLinearGradient(x, y - acum - dimArray[i]/2, 
+                  x + width, y - acum- dimArray[i]/2);
+            }
+            var color = $.rgbToHex($.map($.hexToRgb(colorArray[i % colorLength].slice(1)), 
+                function(v) { return (v * 0.5) >> 0; }));
+            linear.addColorStop(0, color);
+            linear.addColorStop(0.5, colorArray[i % colorLength]);
+            linear.addColorStop(1, color);
+            ctx.fillStyle = linear;
+          }
+          if(horz) {
+            ctx.fillRect(x + acum, y, dimArray[i], height);
+          } else {
+            ctx.fillRect(x, y - acum - dimArray[i], width, dimArray[i]);
+          }
+          if(border && border.name == stringArray[i]) {
+            opt.acum = acum;
+            opt.dimValue = dimArray[i];
+          }
+          acum += (dimArray[i] || 0);
+          valAcum += (valueArray[i] || 0);
+        }
+        if(border) {
+          ctx.save();
+          ctx.lineWidth = 2;
+          ctx.strokeStyle = border.color;
+          if(horz) {
+            ctx.strokeRect(x + opt.acum + 1, y + 1, opt.dimValue -2, height - 2);
+          } else {
+            ctx.strokeRect(x + 1, y - opt.acum - opt.dimValue + 1, width -2, opt.dimValue -2);
+          }
+          ctx.restore();
+        }
+        if(label.type == 'Native') {
+          ctx.save();
+          ctx.fillStyle = ctx.strokeStyle = label.color;
+          ctx.font = label.style + ' ' + label.size + 'px ' + label.family;
+          ctx.textBaseline = 'middle';
+          var aggValue = aggregates(node.name, valAcum, node);
+          if(aggValue !== false) {
+            aggValue = aggValue !== true? aggValue : valAcum;
+            if(horz) {
+              ctx.textAlign = 'right';
+              ctx.fillText(aggValue, x + acum - config.labelOffset, y + height/2);
+            } else {
+              ctx.textAlign = 'center';
+              ctx.fillText(aggValue, x + width/2, y - height - label.size/2 - config.labelOffset);
+            }
+          }
+          if(showLabels(node.name, valAcum, node)) {
+            if(horz) {
+              ctx.textAlign = 'center';
+              ctx.translate(x - config.labelOffset - label.size/2, y + height/2);
+              ctx.rotate(Math.PI / 2);
+              ctx.fillText(node.name, 0, 0);
+            } else {
+              ctx.textAlign = 'center';
+              ctx.fillText(node.name, x + width/2, y + label.size/2 + config.labelOffset);
+            }
+          }
+          ctx.restore();
+        }
+      }
+    },
+    'contains': function(node, mpos) {
+      var pos = node.pos.getc(true), 
+          width = node.getData('width'),
+          height = node.getData('height'),
+          algnPos = this.getAlignedPos(pos, width, height),
+          x = algnPos.x, y = algnPos.y,
+          dimArray = node.getData('dimArray'),
+          config = node.getData('config'),
+          rx = mpos.x - x,
+          horz = config.orientation == 'horizontal';
+      //bounding box check
+      if(horz) {
+        if(mpos.x < x || mpos.x > x + width
+            || mpos.y > y + height || mpos.y < y) {
+            return false;
+          }
+      } else {
+        if(mpos.x < x || mpos.x > x + width
+            || mpos.y > y || mpos.y < y - height) {
+            return false;
+          }
+      }
+      //deep check
+      for(var i=0, l=dimArray.length, acum=(horz? x:y); i<l; i++) {
+        var dimi = dimArray[i];
+        if(horz) {
+          acum += dimi;
+          var intersec = acum;
+          if(mpos.x <= intersec) {
+            return {
+              'name': node.getData('stringArray')[i],
+              'color': node.getData('colorArray')[i],
+              'value': node.getData('valueArray')[i],
+              'label': node.name
+            };
+          }
+        } else {
+          acum -= dimi;
+          var intersec = acum;
+          if(mpos.y >= intersec) {
+            return {
+              'name': node.getData('stringArray')[i],
+              'color': node.getData('colorArray')[i],
+              'value': node.getData('valueArray')[i],
+              'label': node.name
+            };
+          }
+        }
+      }
+      return false;
+    }
+  },
+  'barchart-grouped' : {
+    'render' : function(node, canvas) {
+      var pos = node.pos.getc(true), 
+          width = node.getData('width'),
+          height = node.getData('height'),
+          algnPos = this.getAlignedPos(pos, width, height),
+          x = algnPos.x, y = algnPos.y,
+          dimArray = node.getData('dimArray'),
+          valueArray = node.getData('valueArray'),
+          valueLength = valueArray.length,
+          colorArray = node.getData('colorArray'),
+          colorLength = colorArray.length,
+          stringArray = node.getData('stringArray'); 
+
+      var ctx = canvas.getCtx(),
+          opt = {},
+          border = node.getData('border'),
+          gradient = node.getData('gradient'),
+          config = node.getData('config'),
+          horz = config.orientation == 'horizontal',
+          aggregates = config.showAggregates,
+          showLabels = config.showLabels,
+          label = config.Label,
+          fixedDim = (horz? height : width) / valueLength;
+      
+      if (colorArray && dimArray && stringArray) {
+        for (var i=0, l=valueLength, acum=0, valAcum=0; i<l; i++) {
+          ctx.fillStyle = ctx.strokeStyle = colorArray[i % colorLength];
+          if(gradient) {
+            var linear;
+            if(horz) {
+              linear = ctx.createLinearGradient(x + dimArray[i]/2, y + fixedDim * i, 
+                  x + dimArray[i]/2, y + fixedDim * (i + 1));
+            } else {
+              linear = ctx.createLinearGradient(x + fixedDim * i, y - dimArray[i]/2, 
+                  x + fixedDim * (i + 1), y - dimArray[i]/2);
+            }
+            var color = $.rgbToHex($.map($.hexToRgb(colorArray[i % colorLength].slice(1)), 
+                function(v) { return (v * 0.5) >> 0; }));
+            linear.addColorStop(0, color);
+            linear.addColorStop(0.5, colorArray[i % colorLength]);
+            linear.addColorStop(1, color);
+            ctx.fillStyle = linear;
+          }
+          if(horz) {
+            ctx.fillRect(x, y + fixedDim * i, dimArray[i], fixedDim);
+          } else {
+            ctx.fillRect(x + fixedDim * i, y - dimArray[i], fixedDim, dimArray[i]);
+          }
+          if(border && border.name == stringArray[i]) {
+            opt.acum = fixedDim * i;
+            opt.dimValue = dimArray[i];
+          }
+          acum += (dimArray[i] || 0);
+          valAcum += (valueArray[i] || 0);
+        }
+        if(border) {
+          ctx.save();
+          ctx.lineWidth = 2;
+          ctx.strokeStyle = border.color;
+          if(horz) {
+            ctx.strokeRect(x + 1, y + opt.acum + 1, opt.dimValue -2, fixedDim - 2);
+          } else {
+            ctx.strokeRect(x + opt.acum + 1, y - opt.dimValue + 1, fixedDim -2, opt.dimValue -2);
+          }
+          ctx.restore();
+        }
+        if(label.type == 'Native') {
+          ctx.save();
+          ctx.fillStyle = ctx.strokeStyle = label.color;
+          ctx.font = label.style + ' ' + label.size + 'px ' + label.family;
+          ctx.textBaseline = 'middle';
+          var aggValue = aggregates(node.name, valAcum, node);
+          if(aggValue !== false) {
+            aggValue = aggValue !== true? aggValue : valAcum;
+            if(horz) {
+              ctx.textAlign = 'right';
+              ctx.fillText(aggValue, x + Math.max.apply(null, dimArray) - config.labelOffset, y + height/2);
+            } else {
+              ctx.textAlign = 'center';
+              ctx.fillText(aggValue, x + width/2, y - Math.max.apply(null, dimArray) - label.size/2 - config.labelOffset);
+            }
+          }
+          if(showLabels(node.name, valAcum, node)) {
+            if(horz) {
+              ctx.textAlign = 'center';
+              ctx.translate(x - config.labelOffset - label.size/2, y + height/2);
+              ctx.rotate(Math.PI / 2);
+              ctx.fillText(node.name, 0, 0);
+            } else {
+              ctx.textAlign = 'center';
+              ctx.fillText(node.name, x + width/2, y + label.size/2 + config.labelOffset);
+            }
+          }
+          ctx.restore();
+        }
+      }
+    },
+    'contains': function(node, mpos) {
+      var pos = node.pos.getc(true), 
+          width = node.getData('width'),
+          height = node.getData('height'),
+          algnPos = this.getAlignedPos(pos, width, height),
+          x = algnPos.x, y = algnPos.y,
+          dimArray = node.getData('dimArray'),
+          len = dimArray.length,
+          config = node.getData('config'),
+          rx = mpos.x - x,
+          horz = config.orientation == 'horizontal',
+          fixedDim = (horz? height : width) / len;
+      //bounding box check
+      if(horz) {
+        if(mpos.x < x || mpos.x > x + width
+            || mpos.y > y + height || mpos.y < y) {
+            return false;
+          }
+      } else {
+        if(mpos.x < x || mpos.x > x + width
+            || mpos.y > y || mpos.y < y - height) {
+            return false;
+          }
+      }
+      //deep check
+      for(var i=0, l=dimArray.length; i<l; i++) {
+        var dimi = dimArray[i];
+        if(horz) {
+          var limit = y + fixedDim * i;
+          if(mpos.x <= x+ dimi && mpos.y >= limit && mpos.y <= limit + fixedDim) {
+            return {
+              'name': node.getData('stringArray')[i],
+              'color': node.getData('colorArray')[i],
+              'value': node.getData('valueArray')[i],
+              'label': node.name
+            };
+          }
+        } else {
+          var limit = x + fixedDim * i;
+          if(mpos.x >= limit && mpos.x <= limit + fixedDim && mpos.y >= y - dimi) {
+            return {
+              'name': node.getData('stringArray')[i],
+              'color': node.getData('colorArray')[i],
+              'value': node.getData('valueArray')[i],
+              'label': node.name
+            };
+          }
+        }
+      }
+      return false;
+    }
+  }
+});
+
+/*
+  Class: BarChart
+  
+  A visualization that displays stacked bar charts.
+  
+  Constructor Options:
+  
+  See <Options.BarChart>.
+
+*/
+$jit.BarChart = new Class({
+  st: null,
+  colors: ["#416D9C", "#70A35E", "#EBB056", "#C74243", "#83548B", "#909291", "#557EAA"],
+  selected: {},
+  busy: false,
+  
+  initialize: function(opt) {
+    this.controller = this.config = 
+      $.merge(Options("Canvas", "Margin", "Label", "BarChart"), {
+        Label: { type: 'Native' }
+      }, opt);
+    //set functions for showLabels and showAggregates
+    var showLabels = this.config.showLabels,
+        typeLabels = $.type(showLabels),
+        showAggregates = this.config.showAggregates,
+        typeAggregates = $.type(showAggregates);
+    this.config.showLabels = typeLabels == 'function'? showLabels : $.lambda(showLabels);
+    this.config.showAggregates = typeAggregates == 'function'? showAggregates : $.lambda(showAggregates);
+    
+    this.initializeViz();
+  },
+  
+  initializeViz: function() {
+    var config = this.config, that = this;
+    var nodeType = config.type.split(":")[0],
+        horz = config.orientation == 'horizontal',
+        nodeLabels = {};
+    
+    var delegate = new $jit.ST({
+      injectInto: config.injectInto,
+      width: config.width,
+      height: config.height,
+      orientation: horz? 'left' : 'bottom',
+      levelDistance: 0,
+      siblingOffset: config.barsOffset,
+      subtreeOffset: 0,
+      withLabels: config.Label.type != 'Native',      
+      useCanvas: config.useCanvas,
+      Label: {
+        type: config.Label.type
+      },
+      Node: {
+        overridable: true,
+        type: 'barchart-' + nodeType,
+        align: 'left',
+        width: 1,
+        height: 1
+      },
+      Edge: {
+        type: 'none'
+      },
+      Tips: {
+        enable: config.Tips.enable,
+        type: 'Native',
+        force: true,
+        onShow: function(tip, node, contains) {
+          var elem = contains;
+          config.Tips.onShow(tip, elem, node);
+        }
+      },
+      Events: {
+        enable: true,
+        type: 'Native',
+        onClick: function(node, eventInfo, evt) {
+          if(!config.Events.enable) return;
+          var elem = eventInfo.getContains();
+          config.Events.onClick(elem, eventInfo, evt);
+        },
+        onMouseMove: function(node, eventInfo, evt) {
+          if(!config.hoveredColor) return;
+          if(node) {
+            var elem = eventInfo.getContains();
+            that.select(node.id, elem.name, elem.index);
+          } else {
+            that.select(false, false, false);
+          }
+        }
+      },
+      onCreateLabel: function(domElement, node) {
+        var labelConf = config.Label,
+            valueArray = node.getData('valueArray'),
+            acum = $.reduce(valueArray, function(x, y) { return x + y; }, 0);
+        var nlbs = {
+          wrapper: document.createElement('div'),
+          aggregate: document.createElement('div'),
+          label: document.createElement('div')
+        };
+        var wrapper = nlbs.wrapper,
+            label = nlbs.label,
+            aggregate = nlbs.aggregate,
+            wrapperStyle = wrapper.style,
+            labelStyle = label.style,
+            aggregateStyle = aggregate.style;
+        //store node labels
+        nodeLabels[node.id] = nlbs;
+        //append labels
+        wrapper.appendChild(label);
+        wrapper.appendChild(aggregate);
+        if(!config.showLabels(node.name, acum, node)) {
+          labelStyle.display = 'none';
+        }
+        if(!config.showAggregates(node.name, acum, node)) {
+          aggregateStyle.display = 'none';
+        }
+        wrapperStyle.position = 'relative';
+        wrapperStyle.overflow = 'visible';
+        wrapperStyle.fontSize = labelConf.size + 'px';
+        wrapperStyle.fontFamily = labelConf.family;
+        wrapperStyle.color = labelConf.color;
+        wrapperStyle.textAlign = 'center';
+        aggregateStyle.position = labelStyle.position = 'absolute';
+        
+        domElement.style.width = node.getData('width') + 'px';
+        domElement.style.height = node.getData('height') + 'px';
+        aggregateStyle.left = labelStyle.left =  '0px';
+
+        label.innerHTML = node.name;
+        
+        domElement.appendChild(wrapper);
+      },
+      onPlaceLabel: function(domElement, node) {
+        if(!nodeLabels[node.id]) return;
+        var labels = nodeLabels[node.id],
+            wrapperStyle = labels.wrapper.style,
+            labelStyle = labels.label.style,
+            aggregateStyle = labels.aggregate.style,
+            grouped = config.type.split(':')[0] == 'grouped',
+            horz = config.orientation == 'horizontal',
+            dimArray = node.getData('dimArray'),
+            valArray = node.getData('valueArray'),
+            width = (grouped && horz)? Math.max.apply(null, dimArray) : node.getData('width'),
+            height = (grouped && !horz)? Math.max.apply(null, dimArray) : node.getData('height'),
+            font = parseInt(wrapperStyle.fontSize, 10),
+            domStyle = domElement.style;
+            
+        
+        if(dimArray && valArray) {
+          wrapperStyle.width = aggregateStyle.width = labelStyle.width = domElement.style.width = width + 'px';
+          for(var i=0, l=valArray.length, acum=0; i<l; i++) {
+            if(dimArray[i] > 0) {
+              acum+= valArray[i];
+            }
+          }
+          if(config.showLabels(node.name, acum, node)) {
+            labelStyle.display = '';
+          } else {
+            labelStyle.display = 'none';
+          }
+          var aggValue = config.showAggregates(node.name, acum, node);
+          if(aggValue !== false) {
+            aggregateStyle.display = '';
+          } else {
+            aggregateStyle.display = 'none';
+          }
+          if(config.orientation == 'horizontal') {
+            aggregateStyle.textAlign = 'right';
+            labelStyle.textAlign = 'left';
+            labelStyle.textIndex = aggregateStyle.textIndent = config.labelOffset + 'px';
+            aggregateStyle.top = labelStyle.top = (height-font)/2 + 'px';
+            domElement.style.height = wrapperStyle.height = height + 'px';
+          } else {
+            aggregateStyle.top = (-font - config.labelOffset) + 'px';
+            labelStyle.top = (config.labelOffset + height) + 'px';
+            domElement.style.top = parseInt(domElement.style.top, 10) - height + 'px';
+            domElement.style.height = wrapperStyle.height = height + 'px';
+          }
+          labels.aggregate.innerHTML = aggValue !== true? aggValue : acum;
+        }
+      }
+    });
+    
+    var size = delegate.canvas.getSize(),
+        margin = config.Margin;
+    if(horz) {
+      delegate.config.offsetX = size.width/2 - margin.left
+        - (config.showLabels && (config.labelOffset + config.Label.size));    
+      delegate.config.offsetY = (margin.bottom - margin.top)/2;
+    } else {
+      delegate.config.offsetY = -size.height/2 + margin.bottom 
+        + (config.showLabels && (config.labelOffset + config.Label.size));
+      delegate.config.offsetX = (margin.right - margin.left)/2;
+    }
+    this.delegate = delegate;
+    this.canvas = this.delegate.canvas;
+  },
+  
+  /*
+    Method: loadJSON
+   
+    Loads JSON data into the visualization. 
+    
+    Parameters:
+    
+    json - The JSON data format. This format is described in <http://blog.thejit.org/2010/04/24/new-javascript-infovis-toolkit-visualizations/#json-data-format>.
+    
+    Example:
+    (start code js)
+    var barChart = new $jit.BarChart(options);
+    barChart.loadJSON(json);
+    (end code)
+ */  
+  loadJSON: function(json) {
+    if(this.busy) return;
+    this.busy = true;
+    
+    var prefix = $.time(), 
+        ch = [], 
+        delegate = this.delegate,
+        name = $.splat(json.label), 
+        color = $.splat(json.color || this.colors),
+        config = this.config,
+        gradient = !!config.type.split(":")[1],
+        animate = config.animate,
+        horz = config.orientation == 'horizontal',
+        that = this;
+    
+    for(var i=0, values=json.values, l=values.length; i<l; i++) {
+      var val = values[i]
+      var valArray = $.splat(values[i].values);
+      var acum = 0;
+      ch.push({
+        'id': prefix + val.label,
+        'name': val.label,
+        'data': {
+          'value': valArray,
+          '$valueArray': valArray,
+          '$colorArray': color,
+          '$stringArray': name,
+          '$gradient': gradient,
+          '$config': config
+        },
+        'children': []
+      });
+    }
+    var root = {
+      'id': prefix + '$root',
+      'name': '',
+      'data': {
+        '$type': 'none',
+        '$width': 1,
+        '$height': 1
+      },
+      'children': ch
+    };
+    delegate.loadJSON(root);
+    
+    this.normalizeDims();
+    delegate.compute();
+    delegate.select(delegate.root);
+    if(animate) {
+      if(horz) {
+        delegate.fx.animate({
+          modes: ['node-property:width:dimArray'],
+          duration:1500,
+          onComplete: function() {
+            that.busy = false;
+          }
+        });
+      } else {
+        delegate.fx.animate({
+          modes: ['node-property:height:dimArray'],
+          duration:1500,
+          onComplete: function() {
+            that.busy = false;
+          }
+        });
+      }
+    } else {
+      this.busy = false;
+    }
+  },
+  
+  /*
+    Method: updateJSON
+   
+    Use this method when updating values for the current JSON data. If the items specified by the JSON data already exist in the graph then their values will be updated.
+    
+    Parameters:
+    
+    json - (object) JSON data to be updated. The JSON format corresponds to the one described in <BarChart.loadJSON>.
+    onComplete - (object) A callback object to be called when the animation transition when updating the data end.
+    
+    Example:
+    
+    (start code js)
+    barChart.updateJSON(json, {
+      onComplete: function() {
+        alert('update complete!');
+      }
+    });
+    (end code)
+ */  
+  updateJSON: function(json, onComplete) {
+    if(this.busy) return;
+    this.busy = true;
+    this.select(false, false, false);
+    var delegate = this.delegate;
+    var graph = delegate.graph;
+    var values = json.values;
+    var animate = this.config.animate;
+    var that = this;
+    var horz = this.config.orientation == 'horizontal';
+    $.each(values, function(v) {
+      var n = graph.getByName(v.label);
+      if(n) {
+        n.setData('valueArray', $.splat(v.values));
+        if(json.label) {
+          n.setData('stringArray', $.splat(json.label));
+        }
+      }
+    });
+    this.normalizeDims();
+    delegate.compute();
+    delegate.select(delegate.root);
+    if(animate) {
+      if(horz) {
+        delegate.fx.animate({
+          modes: ['node-property:width:dimArray'],
+          duration:1500,
+          onComplete: function() {
+            that.busy = false;
+            onComplete && onComplete.onComplete();
+          }
+        });
+      } else {
+        delegate.fx.animate({
+          modes: ['node-property:height:dimArray'],
+          duration:1500,
+          onComplete: function() {
+            that.busy = false;
+            onComplete && onComplete.onComplete();
+          }
+        });
+      }
+    }
+  },
+  
+  //adds the little brown bar when hovering the node
+  select: function(id, name) {
+    if(!this.config.hoveredColor) return;
+    var s = this.selected;
+    if(s.id != id || s.name != name) {
+      s.id = id;
+      s.name = name;
+      s.color = this.config.hoveredColor;
+      this.delegate.graph.eachNode(function(n) {
+        if(id == n.id) {
+          n.setData('border', s);
+        } else {
+          n.setData('border', false);
+        }
+      });
+      this.delegate.plot();
+    }
+  },
+  
+  /*
+    Method: getLegend
+   
+    Returns an object containing as keys the legend names and as values hex strings with color values.
+    
+    Example:
+    
+    (start code js)
+    var legend = barChart.getLegend();
+    (end code)
+  */  
+  getLegend: function() {
+    var legend = {};
+    var n;
+    this.delegate.graph.getNode(this.delegate.root).eachAdjacency(function(adj) {
+      n = adj.nodeTo;
+    });
+    var colors = n.getData('colorArray'),
+        len = colors.length;
+    $.each(n.getData('stringArray'), function(s, i) {
+      legend[s] = colors[i % len];
+    });
+    return legend;
+  },
+  
+  /*
+    Method: getMaxValue
+   
+    Returns the maximum accumulated value for the stacks. This method is used for normalizing the graph heights according to the canvas height.
+    
+    Example:
+    
+    (start code js)
+    var ans = barChart.getMaxValue();
+    (end code)
+    
+    In some cases it could be useful to override this method to normalize heights for a group of BarCharts, like when doing small multiples.
+    
+    Example:
+    
+    (start code js)
+    //will return 100 for all BarChart instances,
+    //displaying all of them with the same scale
+    $jit.BarChart.implement({
+      'getMaxValue': function() {
+        return 100;
+      }
+    });
+    (end code)
+    
+  */  
+  getMaxValue: function() {
+    var maxValue = 0, stacked = this.config.type.split(':')[0] == 'stacked';
+    this.delegate.graph.eachNode(function(n) {
+      var valArray = n.getData('valueArray'),
+          acum = 0;
+      if(!valArray) return;
+      if(stacked) {
+        $.each(valArray, function(v) { 
+          acum += +v;
+        });
+      } else {
+        acum = Math.max.apply(null, valArray);
+      }
+      maxValue = maxValue>acum? maxValue:acum;
+    });
+    return maxValue;
+  },
+  
+  setBarType: function(type) {
+    this.config.type = type;
+    this.delegate.config.Node.type = 'barchart-' + type.split(':')[0];
+  },
+  
+  normalizeDims: function() {
+    //number of elements
+    var root = this.delegate.graph.getNode(this.delegate.root), l=0;
+    root.eachAdjacency(function() {
+      l++;
+    });
+    var maxValue = this.getMaxValue() || 1,
+        size = this.delegate.canvas.getSize(),
+        config = this.config,
+        margin = config.Margin,
+        marginWidth = margin.left + margin.right,
+        marginHeight = margin.top + margin.bottom,
+        horz = config.orientation == 'horizontal',
+        fixedDim = (size[horz? 'height':'width'] - (horz? marginHeight:marginWidth) - (l -1) * config.barsOffset) / l,
+        animate = config.animate,
+        height = size[horz? 'width':'height'] - (horz? marginWidth:marginHeight) 
+          - (!horz && config.showAggregates && (config.Label.size + config.labelOffset))
+          - (config.showLabels && (config.Label.size + config.labelOffset)),
+        dim1 = horz? 'height':'width',
+        dim2 = horz? 'width':'height';
+    this.delegate.graph.eachNode(function(n) {
+      var acum = 0, animateValue = [];
+      $.each(n.getData('valueArray'), function(v) {
+        acum += +v;
+        animateValue.push(0);
+      });
+      n.setData(dim1, fixedDim);
+      if(animate) {
+        n.setData(dim2, acum * height / maxValue, 'end');
+        n.setData('dimArray', $.map(n.getData('valueArray'), function(n) { 
+          return n * height / maxValue; 
+        }), 'end');
+        var dimArray = n.getData('dimArray');
+        if(!dimArray) {
+          n.setData('dimArray', animateValue);
+        }
+      } else {
+        n.setData(dim2, acum * height / maxValue);
+        n.setData('dimArray', $.map(n.getData('valueArray'), function(n) { 
+          return n * height / maxValue; 
+        }));
+      }
+    });
+  }
+});
+
+
+/*
+ * File: Options.PieChart.js
+ *
+*/
+/*
+  Object: Options.PieChart
+  
+  <PieChart> options. 
+  Other options included in the PieChart are <Options.Canvas>, <Options.Label>, <Options.Tips> and <Options.Events>.
+  
+  Syntax:
+  
+  (start code js)
+
+  Options.PieChart = {
+    animate: true,
+    offset: 25,
+    sliceOffset:0,
+    labelOffset: 3,
+    type: 'stacked',
+    hoveredColor: '#9fd4ff',
+    showLabels: true,
+    resizeLabels: false,
+    updateHeights: false
+  };  
+
+  (end code)
+  
+  Example:
+  
+  (start code js)
+
+  var pie = new $jit.PieChart({
+    animate: true,
+    sliceOffset: 5,
+    type: 'stacked:gradient'
+  });  
+
+  (end code)
+  
+  Parameters:
+  
+  animate - (boolean) Default's *true*. Whether to add animated transitions when plotting/updating the visualization.
+  offset - (number) Default's *25*. Adds margin between the visualization and the canvas.
+  sliceOffset - (number) Default's *0*. Separation between the center of the canvas and each pie slice.
+  labelOffset - (number) Default's *3*. Adds margin between the label and the default place where it should be drawn.
+  type - (string) Default's *'stacked'*. Stack style. Posible values are 'stacked', 'stacked:gradient' to add gradients.
+  hoveredColor - (boolean|string) Default's *'#9fd4ff'*. Sets the selected color for a hovered pie stack.
+  showLabels - (boolean) Default's *true*. Display the name of the slots.
+  resizeLabels - (boolean|number) Default's *false*. Resize the pie labels according to their stacked values. Set a number for *resizeLabels* to set a font size minimum.
+  updateHeights - (boolean) Default's *false*. Only for mono-valued (most common) pie charts. Resize the height of the pie slices according to their current values.
+
+*/
+Options.PieChart = {
+  $extend: true,
+
+  animate: true,
+  offset: 25, // page offset
+  sliceOffset:0,
+  labelOffset: 3, // label offset
+  type: 'stacked', // gradient
+  hoveredColor: '#9fd4ff',
+  Events: {
+    enable: false,
+    onClick: $.empty
+  },
+  Tips: {
+    enable: false,
+    onShow: $.empty,
+    onHide: $.empty
+  },
+  showLabels: true,
+  resizeLabels: false,
+  
+  //only valid for mono-valued datasets
+  updateHeights: false
+};
+
+/*
+ * Class: Layouts.Radial
+ * 
+ * Implements a Radial Layout.
+ * 
+ * Implemented By:
+ * 
+ * <RGraph>, <Hypertree>
+ * 
+ */
+Layouts.Radial = new Class({
+
+  /*
+   * Method: compute
+   * 
+   * Computes nodes' positions.
+   * 
+   * Parameters:
+   * 
+   * property - _optional_ A <Graph.Node> position property to store the new
+   * positions. Possible values are 'pos', 'end' or 'start'.
+   * 
+   */
+  compute : function(property) {
+    var prop = $.splat(property || [ 'current', 'start', 'end' ]);
+    NodeDim.compute(this.graph, prop, this.config);
+    this.graph.computeLevels(this.root, 0, "ignore");
+    var lengthFunc = this.createLevelDistanceFunc(); 
+    this.computeAngularWidths(prop);
+    this.computePositions(prop, lengthFunc);
+  },
+
+  /*
+   * computePositions
+   * 
+   * Performs the main algorithm for computing node positions.
+   */
+  computePositions : function(property, getLength) {
+    var propArray = property;
+    var graph = this.graph;
+    var root = graph.getNode(this.root);
+    var parent = this.parent;
+    var config = this.config;
+
+    for ( var i=0, l=propArray.length; i < l; i++) {
+      var pi = propArray[i];
+      root.setPos($P(0, 0), pi);
+      root.setData('span', Math.PI * 2, pi);
+    }
+
+    root.angleSpan = {
+      begin : 0,
+      end : 2 * Math.PI
+    };
+
+    graph.eachBFS(this.root, function(elem) {
+      var angleSpan = elem.angleSpan.end - elem.angleSpan.begin;
+      var angleInit = elem.angleSpan.begin;
+      var len = getLength(elem);
+      //Calculate the sum of all angular widths
+      var totalAngularWidths = 0, subnodes = [], maxDim = {};
+      elem.eachSubnode(function(sib) {
+        totalAngularWidths += sib._treeAngularWidth;
+        //get max dim
+        for ( var i=0, l=propArray.length; i < l; i++) {
+          var pi = propArray[i], dim = sib.getData('dim', pi);
+          maxDim[pi] = (pi in maxDim)? (dim > maxDim[pi]? dim : maxDim[pi]) : dim;
+        }
+        subnodes.push(sib);
+      }, "ignore");
+      //Maintain children order
+      //Second constraint for <http://bailando.sims.berkeley.edu/papers/infovis01.htm>
+      if (parent && parent.id == elem.id && subnodes.length > 0
+          && subnodes[0].dist) {
+        subnodes.sort(function(a, b) {
+          return (a.dist >= b.dist) - (a.dist <= b.dist);
+        });
+      }
+      //Calculate nodes positions.
+      for (var k = 0, ls=subnodes.length; k < ls; k++) {
+        var child = subnodes[k];
+        if (!child._flag) {
+          var angleProportion = child._treeAngularWidth / totalAngularWidths * angleSpan;
+          var theta = angleInit + angleProportion / 2;
+
+          for ( var i=0, l=propArray.length; i < l; i++) {
+            var pi = propArray[i];
+            child.setPos($P(theta, len), pi);
+            child.setData('span', angleProportion, pi);
+            child.setData('dim-quotient', child.getData('dim', pi) / maxDim[pi], pi);
+          }
+
+          child.angleSpan = {
+            begin : angleInit,
+            end : angleInit + angleProportion
+          };
+          angleInit += angleProportion;
+        }
+      }
+    }, "ignore");
+  },
+
+  /*
+   * Method: setAngularWidthForNodes
+   * 
+   * Sets nodes angular widths.
+   */
+  setAngularWidthForNodes : function(prop) {
+    this.graph.eachBFS(this.root, function(elem, i) {
+      var diamValue = elem.getData('angularWidth', prop[0]) || 5;
+      elem._angularWidth = diamValue / i;
+    }, "ignore");
+  },
+
+  /*
+   * Method: setSubtreesAngularWidth
+   * 
+   * Sets subtrees angular widths.
+   */
+  setSubtreesAngularWidth : function() {
+    var that = this;
+    this.graph.eachNode(function(elem) {
+      that.setSubtreeAngularWidth(elem);
+    }, "ignore");
+  },
+
+  /*
+   * Method: setSubtreeAngularWidth
+   * 
+   * Sets the angular width for a subtree.
+   */
+  setSubtreeAngularWidth : function(elem) {
+    var that = this, nodeAW = elem._angularWidth, sumAW = 0;
+    elem.eachSubnode(function(child) {
+      that.setSubtreeAngularWidth(child);
+      sumAW += child._treeAngularWidth;
+    }, "ignore");
+    elem._treeAngularWidth = Math.max(nodeAW, sumAW);
+  },
+
+  /*
+   * Method: computeAngularWidths
+   * 
+   * Computes nodes and subtrees angular widths.
+   */
+  computeAngularWidths : function(prop) {
+    this.setAngularWidthForNodes(prop);
+    this.setSubtreesAngularWidth();
+  }
+
+});
+
+
+/*
+ * File: Sunburst.js
+ */
+
+/*
+   Class: Sunburst
+      
+   A radial space filling tree visualization.
+   
+   Inspired by:
+ 
+   Sunburst <http://www.cc.gatech.edu/gvu/ii/sunburst/>.
+   
+   Note:
+   
+   This visualization was built and engineered from scratch, taking only the paper as inspiration, and only shares some features with the visualization described in the paper.
+   
+  Implements:
+  
+  All <Loader> methods
+  
+   Constructor Options:
+   
+   Inherits options from
+   
+   - <Options.Canvas>
+   - <Options.Controller>
+   - <Options.Node>
+   - <Options.Edge>
+   - <Options.Label>
+   - <Options.Events>
+   - <Options.Tips>
+   - <Options.NodeStyles>
+   - <Options.Navigation>
+   
+   Additionally, there are other parameters and some default values changed
+   
+   interpolation - (string) Default's *linear*. Describes the way nodes are interpolated. Possible values are 'linear' and 'polar'.
+   levelDistance - (number) Default's *100*. The distance between levels of the tree. 
+   Node.type - Described in <Options.Node>. Default's to *multipie*.
+   Node.height - Described in <Options.Node>. Default's *0*.
+   Edge.type - Described in <Options.Edge>. Default's *none*.
+   Label.textAlign - Described in <Options.Label>. Default's *start*.
+   Label.textBaseline - Described in <Options.Label>. Default's *middle*.
+     
+   Instance Properties:
+
+   canvas - Access a <Canvas> instance.
+   graph - Access a <Graph> instance.
+   op - Access a <Sunburst.Op> instance.
+   fx - Access a <Sunburst.Plot> instance.
+   labels - Access a <Sunburst.Label> interface implementation.   
+
+*/
+
+$jit.Sunburst = new Class({
+
+  Implements: [ Loader, Extras, Layouts.Radial ],
+
+  initialize: function(controller) {
+    var $Sunburst = $jit.Sunburst;
+
+    var config = {
+      interpolation: 'linear',
+      levelDistance: 100,
+      Node: {
+        'type': 'multipie',
+        'height':0
+      },
+      Edge: {
+        'type': 'none'
+      },
+      Label: {
+        textAlign: 'start',
+        textBaseline: 'middle'
+      }
+    };
+
+    this.controller = this.config = $.merge(Options("Canvas", "Node", "Edge",
+        "Fx", "Tips", "NodeStyles", "Events", "Navigation", "Controller", "Label"), config, controller);
+
+    var canvasConfig = this.config;
+    if(canvasConfig.useCanvas) {
+      this.canvas = canvasConfig.useCanvas;
+      this.config.labelContainer = this.canvas.id + '-label';
+    } else {
+      if(canvasConfig.background) {
+        canvasConfig.background = $.merge({
+          type: 'Circles'
+        }, canvasConfig.background);
+      }
+      this.canvas = new Canvas(this, canvasConfig);
+      this.config.labelContainer = (typeof canvasConfig.injectInto == 'string'? canvasConfig.injectInto : canvasConfig.injectInto.id) + '-label';
+    }
+
+    this.graphOptions = {
+      'klass': Polar,
+      'Node': {
+        'selected': false,
+        'exist': true,
+        'drawn': true
+      }
+    };
+    this.graph = new Graph(this.graphOptions, this.config.Node,
+        this.config.Edge);
+    this.labels = new $Sunburst.Label[canvasConfig.Label.type](this);
+    this.fx = new $Sunburst.Plot(this, $Sunburst);
+    this.op = new $Sunburst.Op(this);
+    this.json = null;
+    this.root = null;
+    this.rotated = null;
+    this.busy = false;
+    // initialize extras
+    this.initializeExtras();
+  },
+
+  /* 
+  
+    createLevelDistanceFunc 
+  
+    Returns the levelDistance function used for calculating a node distance 
+    to its origin. This function returns a function that is computed 
+    per level and not per node, such that all nodes with the same depth will have the 
+    same distance to the origin. The resulting function gets the 
+    parent node as parameter and returns a float.
+
+   */
+  createLevelDistanceFunc: function() {
+    var ld = this.config.levelDistance;
+    return function(elem) {
+      return (elem._depth + 1) * ld;
+    };
+  },
+
+  /* 
+     Method: refresh 
+     
+     Computes positions and plots the tree.
+
+   */
+  refresh: function() {
+    this.compute();
+    this.plot();
+  },
+
+  /*
+   reposition
+  
+   An alias for computing new positions to _endPos_
+
+   See also:
+
+   <Sunburst.compute>
+   
+  */
+  reposition: function() {
+    this.compute('end');
+  },
+
+  /*
+  Method: rotate
+  
+  Rotates the graph so that the selected node is horizontal on the right.
+
+  Parameters:
+  
+  node - (object) A <Graph.Node>.
+  method - (string) Whether to perform an animation or just replot the graph. Possible values are "replot" or "animate".
+  opt - (object) Configuration options merged with this visualization configuration options.
+  
+  See also:
+
+  <Sunburst.rotateAngle>
+  
+  */
+  rotate: function(node, method, opt) {
+    var theta = node.getPos(opt.property || 'current').getp(true).theta;
+    this.rotated = node;
+    this.rotateAngle(-theta, method, opt);
+  },
+
+  /*
+  Method: rotateAngle
+  
+  Rotates the graph of an angle theta.
+  
+   Parameters:
+   
+   node - (object) A <Graph.Node>.
+   method - (string) Whether to perform an animation or just replot the graph. Possible values are "replot" or "animate".
+   opt - (object) Configuration options merged with this visualization configuration options.
+   
+   See also:
+
+   <Sunburst.rotate>
+  
+  */
+  rotateAngle: function(theta, method, opt) {
+    var that = this;
+    var options = $.merge(this.config, opt || {}, {
+      modes: [ 'polar' ]
+    });
+    var prop = opt.property || (method === "animate" ? 'end' : 'current');
+    if(method === 'animate') {
+      this.fx.animation.pause();
+    }
+    this.graph.eachNode(function(n) {
+      var p = n.getPos(prop);
+      p.theta += theta;
+      if (p.theta < 0) {
+        p.theta += Math.PI * 2;
+      }
+    });
+    if (method == 'animate') {
+      this.fx.animate(options);
+    } else if (method == 'replot') {
+      this.fx.plot();
+      this.busy = false;
+    }
+  },
+
+  /*
+   Method: plot
+  
+   Plots the Sunburst. This is a shortcut to *fx.plot*.
+  */
+  plot: function() {
+    this.fx.plot();
+  }
+});
+
+$jit.Sunburst.$extend = true;
+
+(function(Sunburst) {
+
+  /*
+     Class: Sunburst.Op
+
+     Custom extension of <Graph.Op>.
+
+     Extends:
+
+     All <Graph.Op> methods
+     
+     See also:
+     
+     <Graph.Op>
+
+  */
+  Sunburst.Op = new Class( {
+
+    Implements: Graph.Op
+
+  });
+
+  /*
+     Class: Sunburst.Plot
+
+    Custom extension of <Graph.Plot>.
+  
+    Extends:
+  
+    All <Graph.Plot> methods
+    
+    See also:
+    
+    <Graph.Plot>
+  
+  */
+  Sunburst.Plot = new Class( {
+
+    Implements: Graph.Plot
+
+  });
+
+  /*
+    Class: Sunburst.Label
+
+    Custom extension of <Graph.Label>. 
+    Contains custom <Graph.Label.SVG>, <Graph.Label.HTML> and <Graph.Label.Native> extensions.
+  
+    Extends:
+  
+    All <Graph.Label> methods and subclasses.
+  
+    See also:
+  
+    <Graph.Label>, <Graph.Label.Native>, <Graph.Label.HTML>, <Graph.Label.SVG>.
+  
+   */
+  Sunburst.Label = {};
+
+  /*
+     Sunburst.Label.Native
+
+     Custom extension of <Graph.Label.Native>.
+
+     Extends:
+
+     All <Graph.Label.Native> methods
+
+     See also:
+
+     <Graph.Label.Native>
+  */
+  Sunburst.Label.Native = new Class( {
+    Implements: Graph.Label.Native,
+
+    initialize: function(viz) {
+      this.viz = viz;
+      this.label = viz.config.Label;
+      this.config = viz.config;
+    },
+
+    renderLabel: function(canvas, node, controller) {
+      var span = node.getData('span');
+      if(span < Math.PI /2 && Math.tan(span) * 
+          this.config.levelDistance * node._depth < 10) {
+        return;
+      }
+      var ctx = canvas.getCtx();
+      var measure = ctx.measureText(node.name);
+      if (node.id == this.viz.root) {
+        var x = -measure.width / 2, y = 0, thetap = 0;
+        var ld = 0;
+      } else {
+        var indent = 5;
+        var ld = controller.levelDistance - indent;
+        var clone = node.pos.clone();
+        clone.rho += indent;
+        var p = clone.getp(true);
+        var ct = clone.getc(true);
+        var x = ct.x, y = ct.y;
+        // get angle in degrees
+        var pi = Math.PI;
+        var cond = (p.theta > pi / 2 && p.theta < 3 * pi / 2);
+        var thetap = cond ? p.theta + pi : p.theta;
+        if (cond) {
+          x -= Math.abs(Math.cos(p.theta) * measure.width);
+          y += Math.sin(p.theta) * measure.width;
+        } else if (node.id == this.viz.root) {
+          x -= measure.width / 2;
+        }
+      }
+      ctx.save();
+      ctx.translate(x, y);
+      ctx.rotate(thetap);
+      ctx.fillText(node.name, 0, 0);
+      ctx.restore();
+    }
+  });
+
+  /*
+     Sunburst.Label.SVG
+
+    Custom extension of <Graph.Label.SVG>.
+  
+    Extends:
+  
+    All <Graph.Label.SVG> methods
+  
+    See also:
+  
+    <Graph.Label.SVG>
+  
+  */
+  Sunburst.Label.SVG = new Class( {
+    Implements: Graph.Label.SVG,
+
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+
+    /* 
+       placeLabel
+
+       Overrides abstract method placeLabel in <Graph.Plot>.
+
+       Parameters:
+
+       tag - A DOM label element.
+       node - A <Graph.Node>.
+       controller - A configuration/controller object passed to the visualization.
+      
+     */
+    placeLabel: function(tag, node, controller) {
+      var pos = node.pos.getc(true), viz = this.viz, canvas = this.viz.canvas;
+      var radius = canvas.getSize();
+      var labelPos = {
+        x: Math.round(pos.x + radius.width / 2),
+        y: Math.round(pos.y + radius.height / 2)
+      };
+      tag.setAttribute('x', labelPos.x);
+      tag.setAttribute('y', labelPos.y);
+
+      var bb = tag.getBBox();
+      if (bb) {
+        // center the label
+    var x = tag.getAttribute('x');
+    var y = tag.getAttribute('y');
+    // get polar coordinates
+    var p = node.pos.getp(true);
+    // get angle in degrees
+    var pi = Math.PI;
+    var cond = (p.theta > pi / 2 && p.theta < 3 * pi / 2);
+    if (cond) {
+      tag.setAttribute('x', x - bb.width);
+      tag.setAttribute('y', y - bb.height);
+    } else if (node.id == viz.root) {
+      tag.setAttribute('x', x - bb.width / 2);
+    }
+
+    var thetap = cond ? p.theta + pi : p.theta;
+    if(node._depth)
+      tag.setAttribute('transform', 'rotate(' + thetap * 360 / (2 * pi) + ' ' + x
+          + ' ' + y + ')');
+  }
+
+  controller.onPlaceLabel(tag, node);
+}
+  });
+
+  /*
+     Sunburst.Label.HTML
+
+     Custom extension of <Graph.Label.HTML>.
+
+     Extends:
+
+     All <Graph.Label.HTML> methods.
+
+     See also:
+
+     <Graph.Label.HTML>
+
+  */
+  Sunburst.Label.HTML = new Class( {
+    Implements: Graph.Label.HTML,
+
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+    /* 
+       placeLabel
+
+       Overrides abstract method placeLabel in <Graph.Plot>.
+
+       Parameters:
+
+       tag - A DOM label element.
+       node - A <Graph.Node>.
+       controller - A configuration/controller object passed to the visualization.
+      
+     */
+    placeLabel: function(tag, node, controller) {
+      var pos = node.pos.clone(), 
+          canvas = this.viz.canvas,
+          height = node.getData('height'),
+          ldist = ((height || node._depth == 0)? height : this.viz.config.levelDistance) /2,
+          radius = canvas.getSize();
+      pos.rho += ldist;
+      pos = pos.getc(true);
+      
+      var labelPos = {
+        x: Math.round(pos.x + radius.width / 2),
+        y: Math.round(pos.y + radius.height / 2)
+      };
+
+      var style = tag.style;
+      style.left = labelPos.x + 'px';
+      style.top = labelPos.y + 'px';
+      style.display = this.fitsInCanvas(labelPos, canvas) ? '' : 'none';
+
+      controller.onPlaceLabel(tag, node);
+    }
+  });
+
+  /*
+    Class: Sunburst.Plot.NodeTypes
+
+    This class contains a list of <Graph.Node> built-in types. 
+    Node types implemented are 'none', 'pie', 'multipie', 'gradient-pie' and 'gradient-multipie'.
+
+    You can add your custom node types, customizing your visualization to the extreme.
+
+    Example:
+
+    (start code js)
+      Sunburst.Plot.NodeTypes.implement({
+        'mySpecialType': {
+          'render': function(node, canvas) {
+            //print your custom node to canvas
+          },
+          //optional
+          'contains': function(node, pos) {
+            //return true if pos is inside the node or false otherwise
+          }
+        }
+      });
+    (end code)
+
+  */
+  Sunburst.Plot.NodeTypes = new Class( {
+    'none': {
+      'render': $.empty,
+      'contains': $.lambda(false),
+      'anglecontains': function(node, pos) {
+        var span = node.getData('span') / 2, theta = node.pos.theta;
+        var begin = theta - span, end = theta + span;
+        if (begin < 0)
+          begin += Math.PI * 2;
+        var atan = Math.atan2(pos.y, pos.x);
+        if (atan < 0)
+          atan += Math.PI * 2;
+        if (begin > end) {
+          return (atan > begin && atan <= Math.PI * 2) || atan < end;
+        } else {
+          return atan > begin && atan < end;
+        }
+      }
+    },
+
+    'pie': {
+      'render': function(node, canvas) {
+        var span = node.getData('span') / 2, theta = node.pos.theta;
+        var begin = theta - span, end = theta + span;
+        var polarNode = node.pos.getp(true);
+        var polar = new Polar(polarNode.rho, begin);
+        var p1coord = polar.getc(true);
+        polar.theta = end;
+        var p2coord = polar.getc(true);
+
+        var ctx = canvas.getCtx();
+        ctx.beginPath();
+        ctx.moveTo(0, 0);
+        ctx.lineTo(p1coord.x, p1coord.y);
+        ctx.moveTo(0, 0);
+        ctx.lineTo(p2coord.x, p2coord.y);
+        ctx.moveTo(0, 0);
+        ctx.arc(0, 0, polarNode.rho * node.getData('dim-quotient'), begin, end,
+            false);
+        ctx.fill();
+      },
+      'contains': function(node, pos) {
+        if (this.nodeTypes['none'].anglecontains.call(this, node, pos)) {
+          var rho = Math.sqrt(pos.x * pos.x + pos.y * pos.y);
+          var ld = this.config.levelDistance, d = node._depth;
+          return (rho <= ld * d);
+        }
+        return false;
+      }
+    },
+    'multipie': {
+      'render': function(node, canvas) {
+        var height = node.getData('height');
+        var ldist = height? height : this.config.levelDistance;
+        var span = node.getData('span') / 2, theta = node.pos.theta;
+        var begin = theta - span, end = theta + span;
+        var polarNode = node.pos.getp(true);
+
+        var polar = new Polar(polarNode.rho, begin);
+        var p1coord = polar.getc(true);
+
+        polar.theta = end;
+        var p2coord = polar.getc(true);
+
+        polar.rho += ldist;
+        var p3coord = polar.getc(true);
+
+        polar.theta = begin;
+        var p4coord = polar.getc(true);
+
+        var ctx = canvas.getCtx();
+        ctx.moveTo(0, 0);
+        ctx.beginPath();
+        ctx.arc(0, 0, polarNode.rho, begin, end, false);
+        ctx.arc(0, 0, polarNode.rho + ldist, end, begin, true);
+        ctx.moveTo(p1coord.x, p1coord.y);
+        ctx.lineTo(p4coord.x, p4coord.y);
+        ctx.moveTo(p2coord.x, p2coord.y);
+        ctx.lineTo(p3coord.x, p3coord.y);
+        ctx.fill();
+
+        if (node.collapsed) {
+          ctx.save();
+          ctx.lineWidth = 2;
+          ctx.moveTo(0, 0);
+          ctx.beginPath();
+          ctx.arc(0, 0, polarNode.rho + ldist + 5, end - 0.01, begin + 0.01,
+              true);
+          ctx.stroke();
+          ctx.restore();
+        }
+      },
+      'contains': function(node, pos) {
+        if (this.nodeTypes['none'].anglecontains.call(this, node, pos)) {
+          var rho = Math.sqrt(pos.x * pos.x + pos.y * pos.y);
+          var height = node.getData('height');
+          var ldist = height? height : this.config.levelDistance;
+          var ld = this.config.levelDistance, d = node._depth;
+          return (rho >= ld * d) && (rho <= (ld * d + ldist));
+        }
+        return false;
+      }
+    },
+
+    'gradient-multipie': {
+      'render': function(node, canvas) {
+        var ctx = canvas.getCtx();
+        var height = node.getData('height');
+        var ldist = height? height : this.config.levelDistance;
+        var radialGradient = ctx.createRadialGradient(0, 0, node.getPos().rho,
+            0, 0, node.getPos().rho + ldist);
+
+        var colorArray = $.hexToRgb(node.getData('color')), ans = [];
+        $.each(colorArray, function(i) {
+          ans.push(parseInt(i * 0.5, 10));
+        });
+        var endColor = $.rgbToHex(ans);
+        radialGradient.addColorStop(0, endColor);
+        radialGradient.addColorStop(1, node.getData('color'));
+        ctx.fillStyle = radialGradient;
+        this.nodeTypes['multipie'].render.call(this, node, canvas);
+      },
+      'contains': function(node, pos) {
+        return this.nodeTypes['multipie'].contains.call(this, node, pos);
+      }
+    },
+
+    'gradient-pie': {
+      'render': function(node, canvas) {
+        var ctx = canvas.getCtx();
+        var radialGradient = ctx.createRadialGradient(0, 0, 0, 0, 0, node
+            .getPos().rho);
+
+        var colorArray = $.hexToRgb(node.getData('color')), ans = [];
+        $.each(colorArray, function(i) {
+          ans.push(parseInt(i * 0.5, 10));
+        });
+        var endColor = $.rgbToHex(ans);
+        radialGradient.addColorStop(1, endColor);
+        radialGradient.addColorStop(0, node.getData('color'));
+        ctx.fillStyle = radialGradient;
+        this.nodeTypes['pie'].render.call(this, node, canvas);
+      },
+      'contains': function(node, pos) {
+        return this.nodeTypes['pie'].contains.call(this, node, pos);
+      }
+    }
+  });
+
+  /*
+    Class: Sunburst.Plot.EdgeTypes
+
+    This class contains a list of <Graph.Adjacence> built-in types. 
+    Edge types implemented are 'none', 'line' and 'arrow'.
+  
+    You can add your custom edge types, customizing your visualization to the extreme.
+  
+    Example:
+  
+    (start code js)
+      Sunburst.Plot.EdgeTypes.implement({
+        'mySpecialType': {
+          'render': function(adj, canvas) {
+            //print your custom edge to canvas
+          },
+          //optional
+          'contains': function(adj, pos) {
+            //return true if pos is inside the arc or false otherwise
+          }
+        }
+      });
+    (end code)
+  
+  */
+  Sunburst.Plot.EdgeTypes = new Class({
+    'none': $.empty,
+    'line': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        this.edgeHelper.line.render(from, to, canvas);
+      },
+      'contains': function(adj, pos) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        return this.edgeHelper.line.contains(from, to, pos, this.edge.epsilon);
+      }
+    },
+    'arrow': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true),
+            dim = adj.getData('dim'),
+            direction = adj.data.$direction,
+            inv = (direction && direction.length>1 && direction[0] != adj.nodeFrom.id);
+        this.edgeHelper.arrow.render(from, to, dim, inv, canvas);
+      },
+      'contains': function(adj, pos) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        return this.edgeHelper.arrow.contains(from, to, pos, this.edge.epsilon);
+      }
+    },
+    'hyperline': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(),
+            to = adj.nodeTo.pos.getc(),
+            dim = Math.max(from.norm(), to.norm());
+        this.edgeHelper.hyperline.render(from.$scale(1/dim), to.$scale(1/dim), dim, canvas);
+      },
+      'contains': $.lambda(false) //TODO(nico): Implement this!
+    }
+  });
+
+})($jit.Sunburst);
+
+
+/*
+ * File: PieChart.js
+ *
+*/
+
+$jit.Sunburst.Plot.NodeTypes.implement({
+  'piechart-stacked' : {
+    'render' : function(node, canvas) {
+      var pos = node.pos.getp(true),
+          dimArray = node.getData('dimArray'),
+          valueArray = node.getData('valueArray'),
+          colorArray = node.getData('colorArray'),
+          colorLength = colorArray.length,
+          stringArray = node.getData('stringArray'),
+          span = node.getData('span') / 2,
+          theta = node.pos.theta,
+          begin = theta - span,
+          end = theta + span,
+          polar = new Polar;
+    
+      var ctx = canvas.getCtx(), 
+          opt = {},
+          gradient = node.getData('gradient'),
+          border = node.getData('border'),
+          config = node.getData('config'),
+          showLabels = config.showLabels,
+          resizeLabels = config.resizeLabels,
+          label = config.Label;
+
+      var xpos = config.sliceOffset * Math.cos((begin + end) /2);
+      var ypos = config.sliceOffset * Math.sin((begin + end) /2);
+
+      if (colorArray && dimArray && stringArray) {
+        for (var i=0, l=dimArray.length, acum=0, valAcum=0; i<l; i++) {
+          var dimi = dimArray[i], colori = colorArray[i % colorLength];
+          if(dimi <= 0) continue;
+          ctx.fillStyle = ctx.strokeStyle = colori;
+          if(gradient && dimi) {
+            var radialGradient = ctx.createRadialGradient(xpos, ypos, acum + config.sliceOffset,
+                xpos, ypos, acum + dimi + config.sliceOffset);
+            var colorRgb = $.hexToRgb(colori), 
+                ans = $.map(colorRgb, function(i) { return (i * 0.8) >> 0; }),
+                endColor = $.rgbToHex(ans);
+
+            radialGradient.addColorStop(0, colori);
+            radialGradient.addColorStop(0.5, colori);
+            radialGradient.addColorStop(1, endColor);
+            ctx.fillStyle = radialGradient;
+          }
+          
+          polar.rho = acum + config.sliceOffset;
+          polar.theta = begin;
+          var p1coord = polar.getc(true);
+          polar.theta = end;
+          var p2coord = polar.getc(true);
+          polar.rho += dimi;
+          var p3coord = polar.getc(true);
+          polar.theta = begin;
+          var p4coord = polar.getc(true);
+
+          ctx.beginPath();
+          //fixing FF arc method + fill
+          ctx.arc(xpos, ypos, acum + .01, begin, end, false);
+          ctx.arc(xpos, ypos, acum + dimi + .01, end, begin, true);
+          ctx.fill();
+          if(border && border.name == stringArray[i]) {
+            opt.acum = acum;
+            opt.dimValue = dimArray[i];
+            opt.begin = begin;
+            opt.end = end;
+          }
+          acum += (dimi || 0);
+          valAcum += (valueArray[i] || 0);
+        }
+        if(border) {
+          ctx.save();
+          ctx.globalCompositeOperation = "source-over";
+          ctx.lineWidth = 2;
+          ctx.strokeStyle = border.color;
+          var s = begin < end? 1 : -1;
+          ctx.beginPath();
+          //fixing FF arc method + fill
+          ctx.arc(xpos, ypos, opt.acum + .01 + 1, opt.begin, opt.end, false);
+          ctx.arc(xpos, ypos, opt.acum + opt.dimValue + .01 - 1, opt.end, opt.begin, true);
+          ctx.closePath();
+          ctx.stroke();
+          ctx.restore();
+        }
+        if(showLabels && label.type == 'Native') {
+          ctx.save();
+          ctx.fillStyle = ctx.strokeStyle = label.color;
+          var scale = resizeLabels? node.getData('normalizedDim') : 1,
+              fontSize = (label.size * scale) >> 0;
+          fontSize = fontSize < +resizeLabels? +resizeLabels : fontSize;
+          
+          ctx.font = label.style + ' ' + fontSize + 'px ' + label.family;
+          ctx.textBaseline = 'middle';
+          ctx.textAlign = 'center';
+          
+          polar.rho = acum + config.labelOffset + config.sliceOffset;
+          polar.theta = node.pos.theta;
+          var cart = polar.getc(true);
+          
+          ctx.fillText(node.name, cart.x, cart.y);
+          ctx.restore();
+        }
+      }
+    },
+    'contains': function(node, pos) {
+      if (this.nodeTypes['none'].anglecontains.call(this, node, pos)) {
+        var rho = Math.sqrt(pos.x * pos.x + pos.y * pos.y);
+        var ld = this.config.levelDistance, d = node._depth;
+        var config = node.getData('config');
+        if(rho <=ld * d + config.sliceOffset) {
+          var dimArray = node.getData('dimArray');
+          for(var i=0,l=dimArray.length,acum=config.sliceOffset; i<l; i++) {
+            var dimi = dimArray[i];
+            if(rho >= acum && rho <= acum + dimi) {
+              return {
+                name: node.getData('stringArray')[i],
+                color: node.getData('colorArray')[i],
+                value: node.getData('valueArray')[i],
+                label: node.name
+              };
+            }
+            acum += dimi;
+          }
+        }
+        return false;
+        
+      }
+      return false;
+    }
+  }
+});
+
+/*
+  Class: PieChart
+  
+  A visualization that displays stacked bar charts.
+  
+  Constructor Options:
+  
+  See <Options.PieChart>.
+
+*/
+$jit.PieChart = new Class({
+  sb: null,
+  colors: ["#416D9C", "#70A35E", "#EBB056", "#C74243", "#83548B", "#909291", "#557EAA"],
+  selected: {},
+  busy: false,
+  
+  initialize: function(opt) {
+    this.controller = this.config = 
+      $.merge(Options("Canvas", "PieChart", "Label"), {
+        Label: { type: 'Native' }
+      }, opt);
+    this.initializeViz();
+  },
+  
+  initializeViz: function() {
+    var config = this.config, that = this;
+    var nodeType = config.type.split(":")[0];
+    var delegate = new $jit.Sunburst({
+      injectInto: config.injectInto,
+      width: config.width,
+      height: config.height,
+      useCanvas: config.useCanvas,
+      withLabels: config.Label.type != 'Native',
+      Label: {
+        type: config.Label.type
+      },
+      Node: {
+        overridable: true,
+        type: 'piechart-' + nodeType,
+        width: 1,
+        height: 1
+      },
+      Edge: {
+        type: 'none'
+      },
+      Tips: {
+        enable: config.Tips.enable,
+        type: 'Native',
+        force: true,
+        onShow: function(tip, node, contains) {
+          var elem = contains;
+          config.Tips.onShow(tip, elem, node);
+        }
+      },
+      Events: {
+        enable: true,
+        type: 'Native',
+        onClick: function(node, eventInfo, evt) {
+          if(!config.Events.enable) return;
+          var elem = eventInfo.getContains();
+          config.Events.onClick(elem, eventInfo, evt);
+        },
+        onMouseMove: function(node, eventInfo, evt) {
+          if(!config.hoveredColor) return;
+          if(node) {
+            var elem = eventInfo.getContains();
+            that.select(node.id, elem.name, elem.index);
+          } else {
+            that.select(false, false, false);
+          }
+        }
+      },
+      onCreateLabel: function(domElement, node) {
+        var labelConf = config.Label;
+        if(config.showLabels) {
+          var style = domElement.style;
+          style.fontSize = labelConf.size + 'px';
+          style.fontFamily = labelConf.family;
+          style.color = labelConf.color;
+          style.textAlign = 'center';
+          domElement.innerHTML = node.name;
+        }
+      },
+      onPlaceLabel: function(domElement, node) {
+        if(!config.showLabels) return;
+        var pos = node.pos.getp(true),
+            dimArray = node.getData('dimArray'),
+            span = node.getData('span') / 2,
+            theta = node.pos.theta,
+            begin = theta - span,
+            end = theta + span,
+            polar = new Polar;
+      
+        var showLabels = config.showLabels,
+            resizeLabels = config.resizeLabels,
+            label = config.Label;
+        
+        if (dimArray) {
+          for (var i=0, l=dimArray.length, acum=0; i<l; i++) {
+            acum += dimArray[i];
+          }
+          var scale = resizeLabels? node.getData('normalizedDim') : 1,
+              fontSize = (label.size * scale) >> 0;
+          fontSize = fontSize < +resizeLabels? +resizeLabels : fontSize;
+          domElement.style.fontSize = fontSize + 'px';
+          polar.rho = acum + config.labelOffset + config.sliceOffset;
+          polar.theta = (begin + end) / 2;
+          var pos = polar.getc(true);
+          var radius = that.canvas.getSize();
+          var labelPos = {
+            x: Math.round(pos.x + radius.width / 2),
+            y: Math.round(pos.y + radius.height / 2)
+          };
+          domElement.style.left = labelPos.x + 'px';
+          domElement.style.top = labelPos.y + 'px';
+        }
+      }
+    });
+    
+    var size = delegate.canvas.getSize(),
+        min = Math.min;
+    delegate.config.levelDistance = min(size.width, size.height)/2 
+      - config.offset - config.sliceOffset;
+    this.delegate = delegate;
+    this.canvas = this.delegate.canvas;
+    this.canvas.getCtx().globalCompositeOperation = 'lighter';
+  },
+  
+  /*
+    Method: loadJSON
+   
+    Loads JSON data into the visualization. 
+    
+    Parameters:
+    
+    json - The JSON data format. This format is described in <http://blog.thejit.org/2010/04/24/new-javascript-infovis-toolkit-visualizations/#json-data-format>.
+    
+    Example:
+    (start code js)
+    var pieChart = new $jit.PieChart(options);
+    pieChart.loadJSON(json);
+    (end code)
+  */  
+  loadJSON: function(json) {
+    var prefix = $.time(), 
+        ch = [], 
+        delegate = this.delegate,
+        name = $.splat(json.label),
+        nameLength = name.length,
+        color = $.splat(json.color || this.colors),
+        colorLength = color.length,
+        config = this.config,
+        gradient = !!config.type.split(":")[1],
+        animate = config.animate,
+        mono = nameLength == 1;
+    
+    for(var i=0, values=json.values, l=values.length; i<l; i++) {
+      var val = values[i];
+      var valArray = $.splat(val.values);
+      ch.push({
+        'id': prefix + val.label,
+        'name': val.label,
+        'data': {
+          'value': valArray,
+          '$valueArray': valArray,
+          '$colorArray': mono? $.splat(color[i % colorLength]) : color,
+          '$stringArray': name,
+          '$gradient': gradient,
+          '$config': config,
+          '$angularWidth': $.reduce(valArray, function(x,y){return x+y;})
+        },
+        'children': []
+      });
+    }
+    var root = {
+      'id': prefix + '$root',
+      'name': '',
+      'data': {
+        '$type': 'none',
+        '$width': 1,
+        '$height': 1
+      },
+      'children': ch
+    };
+    delegate.loadJSON(root);
+    
+    this.normalizeDims();
+    delegate.refresh();
+    if(animate) {
+      delegate.fx.animate({
+        modes: ['node-property:dimArray'],
+        duration:1500
+      });
+    }
+  },
+  
+  /*
+    Method: updateJSON
+   
+    Use this method when updating values for the current JSON data. If the items specified by the JSON data already exist in the graph then their values will be updated.
+    
+    Parameters:
+    
+    json - (object) JSON data to be updated. The JSON format corresponds to the one described in <PieChart.loadJSON>.
+    onComplete - (object) A callback object to be called when the animation transition when updating the data end.
+    
+    Example:
+    
+    (start code js)
+    pieChart.updateJSON(json, {
+      onComplete: function() {
+        alert('update complete!');
+      }
+    });
+    (end code)
+  */  
+  updateJSON: function(json, onComplete) {
+    if(this.busy) return;
+    this.busy = true;
+    
+    var delegate = this.delegate;
+    var graph = delegate.graph;
+    var values = json.values;
+    var animate = this.config.animate;
+    var that = this;
+    $.each(values, function(v) {
+      var n = graph.getByName(v.label),
+          vals = $.splat(v.values);
+      if(n) {
+        n.setData('valueArray', vals);
+        n.setData('angularWidth', $.reduce(vals, function(x,y){return x+y;}));
+        if(json.label) {
+          n.setData('stringArray', $.splat(json.label));
+        }
+      }
+    });
+    this.normalizeDims();
+    if(animate) {
+      delegate.compute('end');
+      delegate.fx.animate({
+        modes: ['node-property:dimArray:span', 'linear'],
+        duration:1500,
+        onComplete: function() {
+          that.busy = false;
+          onComplete && onComplete.onComplete();
+        }
+      });
+    } else {
+      delegate.refresh();
+    }
+  },
+    
+  //adds the little brown bar when hovering the node
+  select: function(id, name) {
+    if(!this.config.hoveredColor) return;
+    var s = this.selected;
+    if(s.id != id || s.name != name) {
+      s.id = id;
+      s.name = name;
+      s.color = this.config.hoveredColor;
+      this.delegate.graph.eachNode(function(n) {
+        if(id == n.id) {
+          n.setData('border', s);
+        } else {
+          n.setData('border', false);
+        }
+      });
+      this.delegate.plot();
+    }
+  },
+  
+  /*
+    Method: getLegend
+   
+    Returns an object containing as keys the legend names and as values hex strings with color values.
+    
+    Example:
+    
+    (start code js)
+    var legend = pieChart.getLegend();
+    (end code)
+  */  
+  getLegend: function() {
+    var legend = {};
+    var n;
+    this.delegate.graph.getNode(this.delegate.root).eachAdjacency(function(adj) {
+      n = adj.nodeTo;
+    });
+    var colors = n.getData('colorArray'),
+        len = colors.length;
+    $.each(n.getData('stringArray'), function(s, i) {
+      legend[s] = colors[i % len];
+    });
+    return legend;
+  },
+  
+  /*
+    Method: getMaxValue
+   
+    Returns the maximum accumulated value for the stacks. This method is used for normalizing the graph heights according to the canvas height.
+    
+    Example:
+    
+    (start code js)
+    var ans = pieChart.getMaxValue();
+    (end code)
+    
+    In some cases it could be useful to override this method to normalize heights for a group of PieCharts, like when doing small multiples.
+    
+    Example:
+    
+    (start code js)
+    //will return 100 for all PieChart instances,
+    //displaying all of them with the same scale
+    $jit.PieChart.implement({
+      'getMaxValue': function() {
+        return 100;
+      }
+    });
+    (end code)
+    
+  */  
+  getMaxValue: function() {
+    var maxValue = 0;
+    this.delegate.graph.eachNode(function(n) {
+      var valArray = n.getData('valueArray'),
+          acum = 0;
+      $.each(valArray, function(v) { 
+        acum += +v;
+      });
+      maxValue = maxValue>acum? maxValue:acum;
+    });
+    return maxValue;
+  },
+  
+  normalizeDims: function() {
+    //number of elements
+    var root = this.delegate.graph.getNode(this.delegate.root), l=0;
+    root.eachAdjacency(function() {
+      l++;
+    });
+    var maxValue = this.getMaxValue() || 1,
+        config = this.config,
+        animate = config.animate,
+        rho = this.delegate.config.levelDistance;
+    this.delegate.graph.eachNode(function(n) {
+      var acum = 0, animateValue = [];
+      $.each(n.getData('valueArray'), function(v) {
+        acum += +v;
+        animateValue.push(1);
+      });
+      var stat = (animateValue.length == 1) && !config.updateHeights;
+      if(animate) {
+        n.setData('dimArray', $.map(n.getData('valueArray'), function(n) { 
+          return stat? rho: (n * rho / maxValue); 
+        }), 'end');
+        var dimArray = n.getData('dimArray');
+        if(!dimArray) {
+          n.setData('dimArray', animateValue);
+        }
+      } else {
+        n.setData('dimArray', $.map(n.getData('valueArray'), function(n) { 
+          return stat? rho : (n * rho / maxValue); 
+        }));
+      }
+      n.setData('normalizedDim', acum / maxValue);
+    });
+  }
+});
+
+
+/*
+ * Class: Layouts.TM
+ * 
+ * Implements TreeMaps layouts (SliceAndDice, Squarified, Strip).
+ * 
+ * Implemented By:
+ * 
+ * <TM>
+ * 
+ */
+Layouts.TM = {};
+
+Layouts.TM.SliceAndDice = new Class({
+  compute: function(prop) {
+    var root = this.graph.getNode(this.clickedNode && this.clickedNode.id || this.root);
+    this.controller.onBeforeCompute(root);
+    var size = this.canvas.getSize(),
+        config = this.config,
+        width = size.width,
+        height = size.height;
+    this.graph.computeLevels(this.root, 0, "ignore");
+    //set root position and dimensions
+    root.getPos(prop).setc(-width/2, -height/2);
+    root.setData('width', width, prop);
+    root.setData('height', height + config.titleHeight, prop);
+    this.computePositions(root, root, this.layout.orientation, prop);
+    this.controller.onAfterCompute(root);
+  },
+  
+  computePositions: function(par, ch, orn, prop) {
+    //compute children areas
+    var totalArea = 0;
+    par.eachSubnode(function(n) {
+      totalArea += n.getData('area', prop);
+    });
+    
+    var config = this.config,
+        offst = config.offset,
+        width  = par.getData('width', prop),
+        height = Math.max(par.getData('height', prop) - config.titleHeight, 0),
+        fact = par == ch? 1 : (ch.getData('area', prop) / totalArea);
+
+    var otherSize, size, dim, pos, pos2, posth, pos2th;
+    var horizontal = (orn == "h");
+    if(horizontal) {
+      orn = 'v';
+      otherSize = height;
+      size = width * fact;
+      dim = 'height';
+      pos = 'y';
+      pos2 = 'x';
+      posth = config.titleHeight;
+      pos2th = 0;
+    } else {
+      orn = 'h';    
+      otherSize = height * fact;
+      size = width;
+      dim = 'width';
+      pos = 'x';
+      pos2 = 'y';
+      posth = 0;
+      pos2th = config.titleHeight;
+    }
+    var cpos = ch.getPos(prop);
+    ch.setData('width', size, prop);
+    ch.setData('height', otherSize, prop);
+    var offsetSize = 0, tm = this;
+    ch.eachSubnode(function(n) {
+      var p = n.getPos(prop);
+      p[pos] = offsetSize + cpos[pos] + posth;
+      p[pos2] = cpos[pos2] + pos2th;
+      tm.computePositions(ch, n, orn, prop);
+      offsetSize += n.getData(dim, prop);
+    });
+  }
+
+});
+
+Layouts.TM.Area = {
+ /*
+    Method: compute
+ 
+   Called by loadJSON to calculate recursively all node positions and lay out the tree.
+ 
+    Parameters:
+
+       json - A JSON tree. See also <Loader.loadJSON>.
+       coord - A coordinates object specifying width, height, left and top style properties.
+ */
+ compute: function(prop) {
+    prop = prop || "current";
+    var root = this.graph.getNode(this.clickedNode && this.clickedNode.id || this.root);
+    this.controller.onBeforeCompute(root);
+    var config = this.config,
+        size = this.canvas.getSize(),
+        width = size.width,
+        height = size.height,
+        offst = config.offset,
+        offwdth = width - offst,
+        offhght = height - offst;
+    this.graph.computeLevels(this.root, 0, "ignore");
+    //set root position and dimensions
+    root.getPos(prop).setc(-width/2, -height/2);
+    root.setData('width', width, prop);
+    root.setData('height', height, prop);
+    //create a coordinates object
+    var coord = {
+        'top': -height/2 + config.titleHeight,
+        'left': -width/2,
+        'width': offwdth,
+        'height': offhght - config.titleHeight
+    };
+    this.computePositions(root, coord, prop);
+    this.controller.onAfterCompute(root);
+ }, 
+ 
+ /*
+    Method: computeDim
+ 
+   Computes dimensions and positions of a group of nodes
+   according to a custom layout row condition. 
+ 
+    Parameters:
+
+       tail - An array of nodes.  
+       initElem - An array of nodes (containing the initial node to be laid).
+       w - A fixed dimension where nodes will be layed out.
+       coord - A coordinates object specifying width, height, left and top style properties.
+       comp - A custom comparison function
+ */
+ computeDim: function(tail, initElem, w, coord, comp, prop) {
+   if(tail.length + initElem.length == 1) {
+     var l = (tail.length == 1)? tail : initElem;
+     this.layoutLast(l, w, coord, prop);
+     return;
+   }
+   if(tail.length >= 2 && initElem.length == 0) {
+     initElem = [tail.shift()];
+   }
+   if(tail.length == 0) {
+     if(initElem.length > 0) this.layoutRow(initElem, w, coord, prop);
+     return;
+   }
+   var c = tail[0];
+   if(comp(initElem, w) >= comp([c].concat(initElem), w)) {
+     this.computeDim(tail.slice(1), initElem.concat([c]), w, coord, comp, prop);
+   } else {
+     var newCoords = this.layoutRow(initElem, w, coord, prop);
+     this.computeDim(tail, [], newCoords.dim, newCoords, comp, prop);
+   }
+ },
+
+ 
+ /*
+    Method: worstAspectRatio
+ 
+   Calculates the worst aspect ratio of a group of rectangles. 
+       
+    See also:
+       
+       <http://en.wikipedia.org/wiki/Aspect_ratio>
+   
+    Parameters:
+
+     ch - An array of nodes.  
+     w  - The fixed dimension where rectangles are being laid out.
+
+    Returns:
+ 
+        The worst aspect ratio.
+
+
+ */
+ worstAspectRatio: function(ch, w) {
+   if(!ch || ch.length == 0) return Number.MAX_VALUE;
+   var areaSum = 0, maxArea = 0, minArea = Number.MAX_VALUE;
+   for(var i=0, l=ch.length; i<l; i++) {
+     var area = ch[i]._area;
+     areaSum += area; 
+     minArea = minArea < area? minArea : area;
+     maxArea = maxArea > area? maxArea : area; 
+   }
+   var sqw = w * w, sqAreaSum = areaSum * areaSum;
+   return Math.max(sqw * maxArea / sqAreaSum,
+           sqAreaSum / (sqw * minArea));
+ },
+ 
+ /*
+    Method: avgAspectRatio
+ 
+   Calculates the average aspect ratio of a group of rectangles. 
+       
+       See also:
+       
+       <http://en.wikipedia.org/wiki/Aspect_ratio>
+   
+    Parameters:
+
+     ch - An array of nodes.  
+       w - The fixed dimension where rectangles are being laid out.
+
+    Returns:
+ 
+        The average aspect ratio.
+
+
+ */
+ avgAspectRatio: function(ch, w) {
+   if(!ch || ch.length == 0) return Number.MAX_VALUE;
+   var arSum = 0;
+   for(var i=0, l=ch.length; i<l; i++) {
+     var area = ch[i]._area;
+     var h = area / w;
+     arSum += w > h? w / h : h / w;
+   }
+   return arSum / l;
+ },
+
+ /*
+    layoutLast
+ 
+   Performs the layout of the last computed sibling.
+ 
+    Parameters:
+
+       ch - An array of nodes.  
+       w - A fixed dimension where nodes will be layed out.
+     coord - A coordinates object specifying width, height, left and top style properties.
+ */
+ layoutLast: function(ch, w, coord, prop) {
+   var child = ch[0];
+   child.getPos(prop).setc(coord.left, coord.top);
+   child.setData('width', coord.width, prop);
+   child.setData('height', coord.height, prop);
+ }
+};
+
+
+Layouts.TM.Squarified = new Class({
+ Implements: Layouts.TM.Area,
+ 
+ computePositions: function(node, coord, prop) {
+   var config = this.config, 
+       max = Math.max;
+   
+   if (coord.width >= coord.height) 
+     this.layout.orientation = 'h';
+   else
+     this.layout.orientation = 'v';
+   
+   var ch = node.getSubnodes([1, 1], "ignore");
+   if(ch.length > 0) {
+     this.processChildrenLayout(node, ch, coord, prop);
+     for(var i=0, l=ch.length; i<l; i++) {
+       var chi = ch[i], 
+           offst = config.offset,
+           height = max(chi.getData('height', prop) - offst - config.titleHeight, 0),
+           width = max(chi.getData('width', prop) - offst, 0),
+           chipos = chi.getPos(prop);
+
+       coord = {
+         'width': width,
+         'height': height,
+         'top': chipos.y + config.titleHeight,
+         'left': chipos.x
+       };
+       this.computePositions(chi, coord, prop);
+     }
+   }
+ },
+
+ /*
+    Method: processChildrenLayout
+ 
+   Computes children real areas and other useful parameters for performing the Squarified algorithm.
+ 
+    Parameters:
+
+       par - The parent node of the json subtree.  
+       ch - An Array of nodes
+     coord - A coordinates object specifying width, height, left and top style properties.
+ */
+ processChildrenLayout: function(par, ch, coord, prop) {
+   //compute children real areas
+   var parentArea = coord.width * coord.height;
+   var i, l=ch.length, totalChArea=0, chArea = [];
+   for(i=0; i<l; i++) {
+     chArea[i] = parseFloat(ch[i].getData('area', prop));
+     totalChArea += chArea[i];
+   }
+   for(i=0; i<l; i++) {
+     ch[i]._area = parentArea * chArea[i] / totalChArea;
+   }
+   var minimumSideValue = this.layout.horizontal()? coord.height : coord.width;
+   ch.sort(function(a, b) { 
+     var diff = b._area - a._area; 
+     return diff? diff : (b.id == a.id? 0 : (b.id < a.id? 1 : -1)); 
+   });
+   var initElem = [ch[0]];
+   var tail = ch.slice(1);
+   this.squarify(tail, initElem, minimumSideValue, coord, prop);
+ },
+
+ /*
+   Method: squarify
+ 
+   Performs an heuristic method to calculate div elements sizes in order to have a good aspect ratio.
+ 
+    Parameters:
+
+       tail - An array of nodes.  
+       initElem - An array of nodes, containing the initial node to be laid out.
+       w - A fixed dimension where nodes will be laid out.
+       coord - A coordinates object specifying width, height, left and top style properties.
+ */
+ squarify: function(tail, initElem, w, coord, prop) {
+   this.computeDim(tail, initElem, w, coord, this.worstAspectRatio, prop);
+ },
+ 
+ /*
+    Method: layoutRow
+ 
+   Performs the layout of an array of nodes.
+ 
+    Parameters:
+
+       ch - An array of nodes.  
+       w - A fixed dimension where nodes will be laid out.
+       coord - A coordinates object specifying width, height, left and top style properties.
+ */
+ layoutRow: function(ch, w, coord, prop) {
+   if(this.layout.horizontal()) {
+     return this.layoutV(ch, w, coord, prop);
+   } else {
+     return this.layoutH(ch, w, coord, prop);
+   }
+ },
+ 
+ layoutV: function(ch, w, coord, prop) {
+   var totalArea = 0, rnd = function(x) { return x; }; 
+   $.each(ch, function(elem) { totalArea += elem._area; });
+   var width = rnd(totalArea / w), top =  0; 
+   for(var i=0, l=ch.length; i<l; i++) {
+     var h = rnd(ch[i]._area / width);
+     var chi = ch[i];
+     chi.getPos(prop).setc(coord.left, coord.top + top);
+     chi.setData('width', width, prop);
+     chi.setData('height', h, prop);
+     top += h;
+   }
+   var ans = {
+     'height': coord.height,
+     'width': coord.width - width,
+     'top': coord.top,
+     'left': coord.left + width
+   };
+   //take minimum side value.
+   ans.dim = Math.min(ans.width, ans.height);
+   if(ans.dim != ans.height) this.layout.change();
+   return ans;
+ },
+ 
+ layoutH: function(ch, w, coord, prop) {
+   var totalArea = 0; 
+   $.each(ch, function(elem) { totalArea += elem._area; });
+   var height = totalArea / w,
+       top = coord.top, 
+       left = 0;
+   
+   for(var i=0, l=ch.length; i<l; i++) {
+     var chi = ch[i];
+     var w = chi._area / height;
+     chi.getPos(prop).setc(coord.left + left, top);
+     chi.setData('width', w, prop);
+     chi.setData('height', height, prop);
+     left += w;
+   }
+   var ans = {
+     'height': coord.height - height,
+     'width': coord.width,
+     'top': coord.top + height,
+     'left': coord.left
+   };
+   ans.dim = Math.min(ans.width, ans.height);
+   if(ans.dim != ans.width) this.layout.change();
+   return ans;
+ }
+});
+
+Layouts.TM.Strip = new Class({
+  Implements: Layouts.TM.Area,
+
+    /*
+      Method: compute
+    
+     Called by loadJSON to calculate recursively all node positions and lay out the tree.
+    
+      Parameters:
+    
+         json - A JSON subtree. See also <Loader.loadJSON>. 
+       coord - A coordinates object specifying width, height, left and top style properties.
+    */
+    computePositions: function(node, coord, prop) {
+     var  ch = node.getSubnodes([1, 1], "ignore"), 
+          config = this.config,
+          max = Math.max;
+     if(ch.length > 0) {
+       this.processChildrenLayout(node, ch, coord, prop);
+       for(var i=0, l=ch.length; i<l; i++) {
+         var chi = ch[i];
+         var offst = config.offset,
+             height = max(chi.getData('height', prop) - offst - config.titleHeight, 0),
+             width  = max(chi.getData('width', prop)  - offst, 0);
+         var chipos = chi.getPos(prop);
+         coord = {
+           'width': width,
+           'height': height,
+           'top': chipos.y + config.titleHeight,
+           'left': chipos.x
+         };
+         this.computePositions(chi, coord, prop);
+       }
+     }
+    },
+    
+    /*
+      Method: processChildrenLayout
+    
+     Computes children real areas and other useful parameters for performing the Strip algorithm.
+    
+      Parameters:
+    
+         par - The parent node of the json subtree.  
+         ch - An Array of nodes
+         coord - A coordinates object specifying width, height, left and top style properties.
+    */
+    processChildrenLayout: function(par, ch, coord, prop) {
+     //compute children real areas
+      var parentArea = coord.width * coord.height;
+      var i, l=ch.length, totalChArea=0, chArea = [];
+      for(i=0; i<l; i++) {
+        chArea[i] = +ch[i].getData('area', prop);
+        totalChArea += chArea[i];
+      }
+      for(i=0; i<l; i++) {
+        ch[i]._area = parentArea * chArea[i] / totalChArea;
+      }
+     var side = this.layout.horizontal()? coord.width : coord.height;
+     var initElem = [ch[0]];
+     var tail = ch.slice(1);
+     this.stripify(tail, initElem, side, coord, prop);
+    },
+    
+    /*
+      Method: stripify
+    
+     Performs an heuristic method to calculate div elements sizes in order to have 
+     a good compromise between aspect ratio and order.
+    
+      Parameters:
+    
+         tail - An array of nodes.  
+         initElem - An array of nodes.
+         w - A fixed dimension where nodes will be layed out.
+       coord - A coordinates object specifying width, height, left and top style properties.
+    */
+    stripify: function(tail, initElem, w, coord, prop) {
+     this.computeDim(tail, initElem, w, coord, this.avgAspectRatio, prop);
+    },
+    
+    /*
+      Method: layoutRow
+    
+     Performs the layout of an array of nodes.
+    
+      Parameters:
+    
+         ch - An array of nodes.  
+         w - A fixed dimension where nodes will be laid out.
+         coord - A coordinates object specifying width, height, left and top style properties.
+    */
+    layoutRow: function(ch, w, coord, prop) {
+     if(this.layout.horizontal()) {
+       return this.layoutH(ch, w, coord, prop);
+     } else {
+       return this.layoutV(ch, w, coord, prop);
+     }
+    },
+    
+    layoutV: function(ch, w, coord, prop) {
+     var totalArea = 0; 
+     $.each(ch, function(elem) { totalArea += elem._area; });
+     var width = totalArea / w, top =  0; 
+     for(var i=0, l=ch.length; i<l; i++) {
+       var chi = ch[i];
+       var h = chi._area / width;
+       chi.getPos(prop).setc(coord.left, 
+           coord.top + (w - h - top));
+       chi.setData('width', width, prop);
+       chi.setData('height', h, prop);
+       top += h;
+     }
+    
+     return {
+       'height': coord.height,
+       'width': coord.width - width,
+       'top': coord.top,
+       'left': coord.left + width,
+       'dim': w
+     };
+    },
+    
+    layoutH: function(ch, w, coord, prop) {
+     var totalArea = 0; 
+     $.each(ch, function(elem) { totalArea += elem._area; });
+     var height = totalArea / w,
+         top = coord.height - height, 
+         left = 0;
+     
+     for(var i=0, l=ch.length; i<l; i++) {
+       var chi = ch[i];
+       var s = chi._area / height;
+       chi.getPos(prop).setc(coord.left + left, coord.top + top);
+       chi.setData('width', s, prop);
+       chi.setData('height', height, prop);
+       left += s;
+     }
+     return {
+       'height': coord.height - height,
+       'width': coord.width,
+       'top': coord.top,
+       'left': coord.left,
+       'dim': w
+     };
+    }
+ });
+
+
+/*
+ * Class: Layouts.Icicle
+ *
+ * Implements the icicle tree layout.
+ *
+ * Implemented By:
+ *
+ * <Icicle>
+ *
+ */
+
+Layouts.Icicle = new Class({
+ /*
+  * Method: compute
+  *
+  * Called by loadJSON to calculate all node positions.
+  *
+  * Parameters:
+  *
+  * posType - The nodes' position to compute. Either "start", "end" or
+  *            "current". Defaults to "current".
+  */
+  compute: function(posType) {
+    posType = posType || "current";
+
+    var root = this.graph.getNode(this.root),
+        config = this.config,
+        size = this.canvas.getSize(),
+        width = size.width,
+        height = size.height,
+        offset = config.offset,
+        levelsToShow = config.constrained ? config.levelsToShow : Number.MAX_VALUE;
+
+    this.controller.onBeforeCompute(root);
+
+    Graph.Util.computeLevels(this.graph, root.id, 0, "ignore");
+
+    var treeDepth = 0;
+
+    Graph.Util.eachLevel(root, 0, false, function (n, d) { if(d > treeDepth) treeDepth = d; });
+
+    var startNode = this.graph.getNode(this.clickedNode && this.clickedNode.id || root.id);
+    var maxDepth = Math.min(treeDepth, levelsToShow-1);
+    var initialDepth = startNode._depth;
+    if(this.layout.horizontal()) {
+      this.computeSubtree(startNode, -width/2, -height/2, width/(maxDepth+1), height, initialDepth, maxDepth, posType);
+    } else {
+      this.computeSubtree(startNode, -width/2, -height/2, width, height/(maxDepth+1), initialDepth, maxDepth, posType);
+    }
+  },
+
+  computeSubtree: function (root, x, y, width, height, initialDepth, maxDepth, posType) {
+    root.getPos(posType).setc(x, y);
+    root.setData('width', width, posType);
+    root.setData('height', height, posType);
+
+    var nodeLength, prevNodeLength = 0, totalDim = 0;
+    var children = Graph.Util.getSubnodes(root, [1, 1], 'ignore'); // next level from this node
+
+    if(!children.length)
+      return;
+
+    $.each(children, function(e) { totalDim += e.getData('dim'); });
+
+    for(var i=0, l=children.length; i < l; i++) {
+      if(this.layout.horizontal()) {
+        nodeLength = height * children[i].getData('dim') / totalDim;
+        this.computeSubtree(children[i], x+width, y, width, nodeLength, initialDepth, maxDepth, posType);
+        y += nodeLength;
+      } else {
+        nodeLength = width * children[i].getData('dim') / totalDim;
+        this.computeSubtree(children[i], x, y+height, nodeLength, height, initialDepth, maxDepth, posType);
+        x += nodeLength;
+      }
+    }
+  }
+});
+
+
+
+/*
+ * File: Icicle.js
+ *
+*/
+
+/*
+  Class: Icicle
+  
+  Icicle space filling visualization.
+  
+  Implements:
+  
+  All <Loader> methods
+  
+  Constructor Options:
+  
+  Inherits options from
+  
+  - <Options.Canvas>
+  - <Options.Controller>
+  - <Options.Node>
+  - <Options.Edge>
+  - <Options.Label>
+  - <Options.Events>
+  - <Options.Tips>
+  - <Options.NodeStyles>
+  - <Options.Navigation>
+  
+  Additionally, there are other parameters and some default values changed
+
+  orientation - (string) Default's *h*. Whether to set horizontal or vertical layouts. Possible values are 'h' and 'v'.
+  offset - (number) Default's *2*. Boxes offset.
+  constrained - (boolean) Default's *false*. Whether to show the entire tree when loaded or just the number of levels specified by _levelsToShow_.
+  levelsToShow - (number) Default's *3*. The number of levels to show for a subtree. This number is relative to the selected node.
+  animate - (boolean) Default's *false*. Whether to animate transitions.
+  Node.type - Described in <Options.Node>. Default's *rectangle*.
+  Label.type - Described in <Options.Label>. Default's *Native*.
+  duration - Described in <Options.Fx>. Default's *700*.
+  fps - Described in <Options.Fx>. Default's *45*.
+  
+  Instance Properties:
+  
+  canvas - Access a <Canvas> instance.
+  graph - Access a <Graph> instance.
+  op - Access a <Icicle.Op> instance.
+  fx - Access a <Icicle.Plot> instance.
+  labels - Access a <Icicle.Label> interface implementation.
+
+*/
+
+$jit.Icicle = new Class({
+  Implements: [ Loader, Extras, Layouts.Icicle ],
+
+  layout: {
+    orientation: "h",
+    vertical: function(){
+      return this.orientation == "v";
+    },
+    horizontal: function(){
+      return this.orientation == "h";
+    },
+    change: function(){
+      this.orientation = this.vertical()? "h" : "v";
+    }
+  },
+
+  initialize: function(controller) {
+    var config = {
+      animate: false,
+      orientation: "h",
+      offset: 2,
+      levelsToShow: Number.MAX_VALUE,
+      constrained: false,
+      Node: {
+        type: 'rectangle',
+        overridable: true
+      },
+      Edge: {
+        type: 'none'
+      },
+      Label: {
+        type: 'Native'
+      },
+      duration: 700,
+      fps: 45
+    };
+
+    var opts = Options("Canvas", "Node", "Edge", "Fx", "Tips", "NodeStyles",
+                       "Events", "Navigation", "Controller", "Label");
+    this.controller = this.config = $.merge(opts, config, controller);
+    this.layout.orientation = this.config.orientation;
+
+    var canvasConfig = this.config;
+    if (canvasConfig.useCanvas) {
+      this.canvas = canvasConfig.useCanvas;
+      this.config.labelContainer = this.canvas.id + '-label';
+    } else {
+      this.canvas = new Canvas(this, canvasConfig);
+      this.config.labelContainer = (typeof canvasConfig.injectInto == 'string'? canvasConfig.injectInto : canvasConfig.injectInto.id) + '-label';
+    }
+
+    this.graphOptions = {
+      'klass': Complex,
+      'Node': {
+        'selected': false,
+        'exist': true,
+        'drawn': true
+      }
+    };
+
+    this.graph = new Graph(
+      this.graphOptions, this.config.Node, this.config.Edge, this.config.Label);
+
+    this.labels = new $jit.Icicle.Label[this.config.Label.type](this);
+    this.fx = new $jit.Icicle.Plot(this, $jit.Icicle);
+    this.op = new $jit.Icicle.Op(this);
+    this.group = new $jit.Icicle.Group(this);
+    this.clickedNode = null;
+
+    this.initializeExtras();
+  },
+
+  /* 
+    Method: refresh 
+    
+    Computes positions and plots the tree.
+  */
+  refresh: function(){
+    var labelType = this.config.Label.type;
+    if(labelType != 'Native') {
+      var that = this;
+      this.graph.eachNode(function(n) { that.labels.hideLabel(n, false); });
+    }
+    this.compute();
+    this.plot();
+  },
+
+  /* 
+    Method: plot 
+    
+    Plots the Icicle visualization. This is a shortcut to *fx.plot*. 
+  
+   */
+  plot: function(){
+    this.fx.plot(this.config);
+  },
+
+  /* 
+    Method: enter 
+    
+    Sets the node as root.
+    
+     Parameters:
+     
+     node - (object) A <Graph.Node>.
+  
+   */
+  enter: function (node) {
+    if (this.busy)
+      return;
+    this.busy = true;
+
+    var that = this,
+        config = this.config;
+
+    var callback = {
+      onComplete: function() {
+        //compute positions of newly inserted nodes
+        if(config.request)
+          that.compute();
+
+        if(config.animate) {
+          that.graph.nodeList.setDataset(['current', 'end'], {
+            'alpha': [1, 0] //fade nodes
+          });
+
+          Graph.Util.eachSubgraph(node, function(n) {
+            n.setData('alpha', 1, 'end');
+          }, "ignore");
+
+          that.fx.animate({
+            duration: 500,
+            modes:['node-property:alpha'],
+            onComplete: function() {
+              that.clickedNode = node;
+              that.compute('end');
+
+              that.fx.animate({
+                modes:['linear', 'node-property:width:height'],
+                duration: 1000,
+                onComplete: function() {
+                  that.busy = false;
+                  that.clickedNode = node;
+                }
+              });
+            }
+          });
+        } else {
+          that.clickedNode = node;
+          that.busy = false;
+          that.refresh();
+        }
+      }
+    };
+
+    if(config.request) {
+      this.requestNodes(clickedNode, callback);
+    } else {
+      callback.onComplete();
+    }
+  },
+
+  /* 
+    Method: out 
+    
+    Sets the parent node of the current selected node as root.
+  
+   */
+  out: function(){
+    if(this.busy)
+      return;
+
+    var that = this,
+        GUtil = Graph.Util,
+        config = this.config,
+        graph = this.graph,
+        parents = GUtil.getParents(graph.getNode(this.clickedNode && this.clickedNode.id || this.root)),
+        parent = parents[0],
+        clickedNode = parent,
+        previousClickedNode = this.clickedNode;
+
+    this.busy = true;
+    this.events.hoveredNode = false;
+
+    if(!parent) {
+      this.busy = false;
+      return;
+    }
+
+    //final plot callback
+    callback = {
+      onComplete: function() {
+        that.clickedNode = parent;
+        if(config.request) {
+          that.requestNodes(parent, {
+            onComplete: function() {
+              that.compute();
+              that.plot();
+              that.busy = false;
+            }
+          });
+        } else {
+          that.compute();
+          that.plot();
+          that.busy = false;
+        }
+      }
+    };
+
+    //animate node positions
+    if(config.animate) {
+      this.clickedNode = clickedNode;
+      this.compute('end');
+      //animate the visible subtree only
+      this.clickedNode = previousClickedNode;
+      this.fx.animate({
+        modes:['linear', 'node-property:width:height'],
+        duration: 1000,
+        onComplete: function() {
+          //animate the parent subtree
+          that.clickedNode = clickedNode;
+          //change nodes alpha
+          graph.nodeList.setDataset(['current', 'end'], {
+            'alpha': [0, 1]
+          });
+          GUtil.eachSubgraph(previousClickedNode, function(node) {
+            node.setData('alpha', 1);
+          }, "ignore");
+          that.fx.animate({
+            duration: 500,
+            modes:['node-property:alpha'],
+            onComplete: function() {
+              callback.onComplete();
+            }
+          });
+        }
+      });
+    } else {
+      callback.onComplete();
+    }
+  },
+  requestNodes: function(node, onComplete){
+    var handler = $.merge(this.controller, onComplete),
+        levelsToShow = this.config.constrained ? this.config.levelsToShow : Number.MAX_VALUE;
+
+    if (handler.request) {
+      var leaves = [], d = node._depth;
+      Graph.Util.eachLevel(node, 0, levelsToShow, function(n){
+        if (n.drawn && !Graph.Util.anySubnode(n)) {
+          leaves.push(n);
+          n._level = n._depth - d;
+          if (this.config.constrained)
+            n._level = levelsToShow - n._level;
+
+        }
+      });
+      this.group.requestNodes(leaves, handler);
+    } else {
+      handler.onComplete();
+    }
+  }
+});
+
+/*
+  Class: Icicle.Op
+  
+  Custom extension of <Graph.Op>.
+  
+  Extends:
+  
+  All <Graph.Op> methods
+  
+  See also:
+  
+  <Graph.Op>
+  
+  */
+$jit.Icicle.Op = new Class({
+
+  Implements: Graph.Op
+
+});
+
+/*
+ * Performs operations on group of nodes.
+ */
+$jit.Icicle.Group = new Class({
+
+  initialize: function(viz){
+    this.viz = viz;
+    this.canvas = viz.canvas;
+    this.config = viz.config;
+  },
+
+  /*
+   * Calls the request method on the controller to request a subtree for each node.
+   */
+  requestNodes: function(nodes, controller){
+    var counter = 0, len = nodes.length, nodeSelected = {};
+    var complete = function(){
+      controller.onComplete();
+    };
+    var viz = this.viz;
+    if (len == 0)
+      complete();
+    for(var i = 0; i < len; i++) {
+      nodeSelected[nodes[i].id] = nodes[i];
+      controller.request(nodes[i].id, nodes[i]._level, {
+        onComplete: function(nodeId, data){
+          if (data && data.children) {
+            data.id = nodeId;
+            viz.op.sum(data, {
+              type: 'nothing'
+            });
+          }
+          if (++counter == len) {
+            Graph.Util.computeLevels(viz.graph, viz.root, 0);
+            complete();
+          }
+        }
+      });
+    }
+  }
+});
+
+/*
+  Class: Icicle.Plot
+  
+  Custom extension of <Graph.Plot>.
+  
+  Extends:
+  
+  All <Graph.Plot> methods
+  
+  See also:
+  
+  <Graph.Plot>
+  
+  */
+$jit.Icicle.Plot = new Class({
+  Implements: Graph.Plot,
+
+  plot: function(opt, animating){
+    opt = opt || this.viz.controller;
+    var viz = this.viz,
+        graph = viz.graph,
+        root = graph.getNode(viz.clickedNode && viz.clickedNode.id || viz.root),
+        initialDepth = root._depth;
+
+    viz.canvas.clear();
+    this.plotTree(root, $.merge(opt, {
+      'withLabels': true,
+      'hideLabels': false,
+      'plotSubtree': function(root, node) {
+        return !viz.config.constrained ||
+               (node._depth - initialDepth < viz.config.levelsToShow);
+      }
+    }), animating);
+  }
+});
+
+/*
+  Class: Icicle.Label
+  
+  Custom extension of <Graph.Label>. 
+  Contains custom <Graph.Label.SVG>, <Graph.Label.HTML> and <Graph.Label.Native> extensions.
+  
+  Extends:
+  
+  All <Graph.Label> methods and subclasses.
+  
+  See also:
+  
+  <Graph.Label>, <Graph.Label.Native>, <Graph.Label.HTML>, <Graph.Label.SVG>.
+  
+  */
+$jit.Icicle.Label = {};
+
+/*
+  Icicle.Label.Native
+  
+  Custom extension of <Graph.Label.Native>.
+  
+  Extends:
+  
+  All <Graph.Label.Native> methods
+  
+  See also:
+  
+  <Graph.Label.Native>
+
+  */
+$jit.Icicle.Label.Native = new Class({
+  Implements: Graph.Label.Native,
+
+  renderLabel: function(canvas, node, controller) {
+    var ctx = canvas.getCtx(),
+        width = node.getData('width'),
+        height = node.getData('height'),
+        size = node.getLabelData('size'),
+        m = ctx.measureText(node.name);
+
+    // Guess as much as possible if the label will fit in the node
+    if(height < (size * 1.5) || width < m.width)
+      return;
+
+    var pos = node.pos.getc(true);
+    ctx.fillText(node.name,
+                 pos.x + width / 2,
+                 pos.y + height / 2);
+  }
+});
+
+/*
+  Icicle.Label.SVG
+  
+  Custom extension of <Graph.Label.SVG>.
+  
+  Extends:
+  
+  All <Graph.Label.SVG> methods
+  
+  See also:
+  
+  <Graph.Label.SVG>
+*/
+$jit.Icicle.Label.SVG = new Class( {
+  Implements: Graph.Label.SVG,
+
+  initialize: function(viz){
+    this.viz = viz;
+  },
+
+  /*
+    placeLabel
+   
+    Overrides abstract method placeLabel in <Graph.Plot>.
+   
+    Parameters:
+   
+    tag - A DOM label element.
+    node - A <Graph.Node>.
+    controller - A configuration/controller object passed to the visualization.
+   */
+  placeLabel: function(tag, node, controller){
+    var pos = node.pos.getc(true), canvas = this.viz.canvas;
+    var radius = canvas.getSize();
+    var labelPos = {
+      x: Math.round(pos.x + radius.width / 2),
+      y: Math.round(pos.y + radius.height / 2)
+    };
+    tag.setAttribute('x', labelPos.x);
+    tag.setAttribute('y', labelPos.y);
+
+    controller.onPlaceLabel(tag, node);
+  }
+});
+
+/*
+  Icicle.Label.HTML
+  
+  Custom extension of <Graph.Label.HTML>.
+  
+  Extends:
+  
+  All <Graph.Label.HTML> methods.
+  
+  See also:
+  
+  <Graph.Label.HTML>
+  
+  */
+$jit.Icicle.Label.HTML = new Class( {
+  Implements: Graph.Label.HTML,
+
+  initialize: function(viz){
+    this.viz = viz;
+  },
+
+  /*
+    placeLabel
+   
+    Overrides abstract method placeLabel in <Graph.Plot>.
+   
+    Parameters:
+   
+    tag - A DOM label element.
+    node - A <Graph.Node>.
+    controller - A configuration/controller object passed to the visualization.
+   */
+  placeLabel: function(tag, node, controller){
+    var pos = node.pos.getc(true), canvas = this.viz.canvas;
+    var radius = canvas.getSize();
+    var labelPos = {
+      x: Math.round(pos.x + radius.width / 2),
+      y: Math.round(pos.y + radius.height / 2)
+    };
+
+    var style = tag.style;
+    style.left = labelPos.x + 'px';
+    style.top = labelPos.y + 'px';
+    style.display = '';
+
+    controller.onPlaceLabel(tag, node);
+  }
+});
+
+/*
+  Class: Icicle.Plot.NodeTypes
+  
+  This class contains a list of <Graph.Node> built-in types. 
+  Node types implemented are 'none', 'rectangle'.
+  
+  You can add your custom node types, customizing your visualization to the extreme.
+  
+  Example:
+  
+  (start code js)
+    Icicle.Plot.NodeTypes.implement({
+      'mySpecialType': {
+        'render': function(node, canvas) {
+          //print your custom node to canvas
+        },
+        //optional
+        'contains': function(node, pos) {
+          //return true if pos is inside the node or false otherwise
+        }
+      }
+    });
+  (end code)
+  
+  */
+$jit.Icicle.Plot.NodeTypes = new Class( {
+  'none': {
+    'render': $.empty
+  },
+
+  'rectangle': {
+    'render': function(node, canvas, animating) {
+      var config = this.viz.config;
+      var offset = config.offset;
+      var width = node.getData('width');
+      var height = node.getData('height');
+      var border = node.getData('border');
+      var pos = node.pos.getc(true);
+      var posx = pos.x + offset / 2, posy = pos.y + offset / 2;
+      var ctx = canvas.getCtx();
+      
+      if(width - offset < 2 || height - offset < 2) return;
+      
+      if(config.cushion) {
+        var color = node.getData('color');
+        var lg = ctx.createRadialGradient(posx + (width - offset)/2, 
+                                          posy + (height - offset)/2, 1, 
+                                          posx + (width-offset)/2, posy + (height-offset)/2, 
+                                          width < height? height : width);
+        var colorGrad = $.rgbToHex($.map($.hexToRgb(color), 
+            function(r) { return r * 0.3 >> 0; }));
+        lg.addColorStop(0, color);
+        lg.addColorStop(1, colorGrad);
+        ctx.fillStyle = lg;
+      }
+
+      if (border) {
+        ctx.strokeStyle = border;
+        ctx.lineWidth = 3;
+      }
+
+      ctx.fillRect(posx, posy, Math.max(0, width - offset), Math.max(0, height - offset));
+      border && ctx.strokeRect(pos.x, pos.y, width, height);
+    },
+
+    'contains': function(node, pos) {
+      if(this.viz.clickedNode && !$jit.Graph.Util.isDescendantOf(node, this.viz.clickedNode.id)) return false;
+      var npos = node.pos.getc(true),
+          width = node.getData('width'),
+          height = node.getData('height');
+      return this.nodeHelper.rectangle.contains({x: npos.x + width/2, y: npos.y + height/2}, pos, width, height);
+    }
+  }
+});
+
+$jit.Icicle.Plot.EdgeTypes = new Class( {
+  'none': $.empty
+});
+
+
+
+/*
+ * File: Layouts.ForceDirected.js
+ *
+*/
+
+/*
+ * Class: Layouts.ForceDirected
+ * 
+ * Implements a Force Directed Layout.
+ * 
+ * Implemented By:
+ * 
+ * <ForceDirected>
+ * 
+ * Credits:
+ * 
+ * Marcus Cobden <http://marcuscobden.co.uk>
+ * 
+ */
+Layouts.ForceDirected = new Class({
+
+  getOptions: function(random) {
+    var s = this.canvas.getSize();
+    var w = s.width, h = s.height;
+    //count nodes
+    var count = 0;
+    this.graph.eachNode(function(n) { 
+      count++;
+    });
+    var k2 = w * h / count, k = Math.sqrt(k2);
+    var l = this.config.levelDistance;
+    
+    return {
+      width: w,
+      height: h,
+      tstart: w * 0.1,
+      nodef: function(x) { return k2 / (x || 1); },
+      edgef: function(x) { return /* x * x / k; */ k * (x - l); }
+    };
+  },
+  
+  compute: function(property, incremental) {
+    var prop = $.splat(property || ['current', 'start', 'end']);
+    var opt = this.getOptions();
+    NodeDim.compute(this.graph, prop, this.config);
+    this.graph.computeLevels(this.root, 0, "ignore");
+    this.graph.eachNode(function(n) {
+      $.each(prop, function(p) {
+        var pos = n.getPos(p);
+        if(pos.equals(Complex.KER)) {
+          pos.x = opt.width/5 * (Math.random() - 0.5);
+          pos.y = opt.height/5 * (Math.random() - 0.5);
+        }
+        //initialize disp vector
+        n.disp = {};
+        $.each(prop, function(p) {
+          n.disp[p] = $C(0, 0);
+        });
+      });
+    });
+    this.computePositions(prop, opt, incremental);
+  },
+  
+  computePositions: function(property, opt, incremental) {
+    var times = this.config.iterations, i = 0, that = this;
+    if(incremental) {
+      (function iter() {
+        for(var total=incremental.iter, j=0; j<total; j++) {
+          opt.t = opt.tstart;
+          if(times) opt.t *= (1 - i++/(times -1));
+          that.computePositionStep(property, opt);
+          if(times && i >= times) {
+            incremental.onComplete();
+            return;
+          }
+        }
+        incremental.onStep(Math.round(i / (times -1) * 100));
+        setTimeout(iter, 1);
+      })();
+    } else {
+      for(; i < times; i++) {
+        opt.t = opt.tstart * (1 - i/(times -1));
+        this.computePositionStep(property, opt);
+      }
+    }
+  },
+  
+  computePositionStep: function(property, opt) {
+    var graph = this.graph;
+    var min = Math.min, max = Math.max;
+    var dpos = $C(0, 0);
+    //calculate repulsive forces
+    graph.eachNode(function(v) {
+      //initialize disp
+      $.each(property, function(p) {
+        v.disp[p].x = 0; v.disp[p].y = 0;
+      });
+      graph.eachNode(function(u) {
+        if(u.id != v.id) {
+          $.each(property, function(p) {
+            var vp = v.getPos(p), up = u.getPos(p);
+            dpos.x = vp.x - up.x;
+            dpos.y = vp.y - up.y;
+            var norm = dpos.norm() || 1;
+            v.disp[p].$add(dpos
+                .$scale(opt.nodef(norm) / norm));
+          });
+        }
+      });
+    });
+    //calculate attractive forces
+    var T = !!graph.getNode(this.root).visited;
+    graph.eachNode(function(node) {
+      node.eachAdjacency(function(adj) {
+        var nodeTo = adj.nodeTo;
+        if(!!nodeTo.visited === T) {
+          $.each(property, function(p) {
+            var vp = node.getPos(p), up = nodeTo.getPos(p);
+            dpos.x = vp.x - up.x;
+            dpos.y = vp.y - up.y;
+            var norm = dpos.norm() || 1;
+            node.disp[p].$add(dpos.$scale(-opt.edgef(norm) / norm));
+            nodeTo.disp[p].$add(dpos.$scale(-1));
+          });
+        }
+      });
+      node.visited = !T;
+    });
+    //arrange positions to fit the canvas
+    var t = opt.t, w2 = opt.width / 2, h2 = opt.height / 2;
+    graph.eachNode(function(u) {
+      $.each(property, function(p) {
+        var disp = u.disp[p];
+        var norm = disp.norm() || 1;
+        var p = u.getPos(p);
+        p.$add($C(disp.x * min(Math.abs(disp.x), t) / norm, 
+            disp.y * min(Math.abs(disp.y), t) / norm));
+        p.x = min(w2, max(-w2, p.x));
+        p.y = min(h2, max(-h2, p.y));
+      });
+    });
+  }
+});
+
+/*
+ * File: ForceDirected.js
+ */
+
+/*
+   Class: ForceDirected
+      
+   A visualization that lays graphs using a Force-Directed layout algorithm.
+   
+   Inspired by:
+  
+   Force-Directed Drawing Algorithms (Stephen G. Kobourov) <http://www.cs.brown.edu/~rt/gdhandbook/chapters/force-directed.pdf>
+   
+  Implements:
+  
+  All <Loader> methods
+  
+   Constructor Options:
+   
+   Inherits options from
+   
+   - <Options.Canvas>
+   - <Options.Controller>
+   - <Options.Node>
+   - <Options.Edge>
+   - <Options.Label>
+   - <Options.Events>
+   - <Options.Tips>
+   - <Options.NodeStyles>
+   - <Options.Navigation>
+   
+   Additionally, there are two parameters
+   
+   levelDistance - (number) Default's *50*. The natural length desired for the edges.
+   iterations - (number) Default's *50*. The number of iterations for the spring layout simulation. Depending on the browser's speed you could set this to a more 'interesting' number, like *200*. 
+     
+   Instance Properties:
+
+   canvas - Access a <Canvas> instance.
+   graph - Access a <Graph> instance.
+   op - Access a <ForceDirected.Op> instance.
+   fx - Access a <ForceDirected.Plot> instance.
+   labels - Access a <ForceDirected.Label> interface implementation.
+
+*/
+
+$jit.ForceDirected = new Class( {
+
+  Implements: [ Loader, Extras, Layouts.ForceDirected ],
+
+  initialize: function(controller) {
+    var $ForceDirected = $jit.ForceDirected;
+
+    var config = {
+      iterations: 50,
+      levelDistance: 50
+    };
+
+    this.controller = this.config = $.merge(Options("Canvas", "Node", "Edge",
+        "Fx", "Tips", "NodeStyles", "Events", "Navigation", "Controller", "Label"), config, controller);
+
+    var canvasConfig = this.config;
+    if(canvasConfig.useCanvas) {
+      this.canvas = canvasConfig.useCanvas;
+      this.config.labelContainer = this.canvas.id + '-label';
+    } else {
+      if(canvasConfig.background) {
+        canvasConfig.background = $.merge({
+          type: 'Circles'
+        }, canvasConfig.background);
+      }
+      this.canvas = new Canvas(this, canvasConfig);
+      this.config.labelContainer = (typeof canvasConfig.injectInto == 'string'? canvasConfig.injectInto : canvasConfig.injectInto.id) + '-label';
+    }
+
+    this.graphOptions = {
+      'klass': Complex,
+      'Node': {
+        'selected': false,
+        'exist': true,
+        'drawn': true
+      }
+    };
+    this.graph = new Graph(this.graphOptions, this.config.Node,
+        this.config.Edge);
+    this.labels = new $ForceDirected.Label[canvasConfig.Label.type](this);
+    this.fx = new $ForceDirected.Plot(this, $ForceDirected);
+    this.op = new $ForceDirected.Op(this);
+    this.json = null;
+    this.busy = false;
+    // initialize extras
+    this.initializeExtras();
+  },
+
+  /* 
+    Method: refresh 
+    
+    Computes positions and plots the tree.
+  */
+  refresh: function() {
+    this.compute();
+    this.plot();
+  },
+
+  reposition: function() {
+    this.compute('end');
+  },
+
+/*
+  Method: computeIncremental
+  
+  Performs the Force Directed algorithm incrementally.
+  
+  Description:
+  
+  ForceDirected algorithms can perform many computations and lead to JavaScript taking too much time to complete. 
+  This method splits the algorithm into smaller parts allowing the user to track the evolution of the algorithm and 
+  avoiding browser messages such as "This script is taking too long to complete".
+  
+  Parameters:
+  
+  opt - (object) The object properties are described below
+  
+  iter - (number) Default's *20*. Split the algorithm into pieces of _iter_ iterations. For example, if the _iterations_ configuration property 
+  of your <ForceDirected> class is 100, then you could set _iter_ to 20 to split the main algorithm into 5 smaller pieces.
+  
+  property - (string) Default's *end*. Whether to update starting, current or ending node positions. Possible values are 'end', 'start', 'current'. 
+  You can also set an array of these properties. If you'd like to keep the current node positions but to perform these 
+  computations for final animation positions then you can just choose 'end'.
+  
+  onStep - (function) A callback function called when each "small part" of the algorithm completed. This function gets as first formal 
+  parameter a percentage value.
+  
+  onComplete - A callback function called when the algorithm completed.
+  
+  Example:
+  
+  In this example I calculate the end positions and then animate the graph to those positions
+  
+  (start code js)
+  var fd = new $jit.ForceDirected(...);
+  fd.computeIncremental({
+    iter: 20,
+    property: 'end',
+    onStep: function(perc) {
+      Log.write("loading " + perc + "%");
+    },
+    onComplete: function() {
+      Log.write("done");
+      fd.animate();
+    }
+  });
+  (end code)
+  
+  In this example I calculate all positions and (re)plot the graph
+  
+  (start code js)
+  var fd = new ForceDirected(...);
+  fd.computeIncremental({
+    iter: 20,
+    property: ['end', 'start', 'current'],
+    onStep: function(perc) {
+      Log.write("loading " + perc + "%");
+    },
+    onComplete: function() {
+      Log.write("done");
+      fd.plot();
+    }
+  });
+  (end code)
+  
+  */
+  computeIncremental: function(opt) {
+    opt = $.merge( {
+      iter: 20,
+      property: 'end',
+      onStep: $.empty,
+      onComplete: $.empty
+    }, opt || {});
+
+    this.config.onBeforeCompute(this.graph.getNode(this.root));
+    this.compute(opt.property, opt);
+  },
+
+  /*
+    Method: plot
+   
+    Plots the ForceDirected graph. This is a shortcut to *fx.plot*.
+   */
+  plot: function() {
+    this.fx.plot();
+  },
+
+  /*
+     Method: animate
+    
+     Animates the graph from the current positions to the 'end' node positions.
+  */
+  animate: function(opt) {
+    this.fx.animate($.merge( {
+      modes: [ 'linear' ]
+    }, opt || {}));
+  }
+});
+
+$jit.ForceDirected.$extend = true;
+
+(function(ForceDirected) {
+
+  /*
+     Class: ForceDirected.Op
+     
+     Custom extension of <Graph.Op>.
+
+     Extends:
+
+     All <Graph.Op> methods
+     
+     See also:
+     
+     <Graph.Op>
+
+  */
+  ForceDirected.Op = new Class( {
+
+    Implements: Graph.Op
+
+  });
+
+  /*
+    Class: ForceDirected.Plot
+    
+    Custom extension of <Graph.Plot>.
+  
+    Extends:
+  
+    All <Graph.Plot> methods
+    
+    See also:
+    
+    <Graph.Plot>
+  
+  */
+  ForceDirected.Plot = new Class( {
+
+    Implements: Graph.Plot
+
+  });
+
+  /*
+    Class: ForceDirected.Label
+    
+    Custom extension of <Graph.Label>. 
+    Contains custom <Graph.Label.SVG>, <Graph.Label.HTML> and <Graph.Label.Native> extensions.
+  
+    Extends:
+  
+    All <Graph.Label> methods and subclasses.
+  
+    See also:
+  
+    <Graph.Label>, <Graph.Label.Native>, <Graph.Label.HTML>, <Graph.Label.SVG>.
+  
+  */
+  ForceDirected.Label = {};
+
+  /*
+     ForceDirected.Label.Native
+     
+     Custom extension of <Graph.Label.Native>.
+
+     Extends:
+
+     All <Graph.Label.Native> methods
+
+     See also:
+
+     <Graph.Label.Native>
+
+  */
+  ForceDirected.Label.Native = new Class( {
+    Implements: Graph.Label.Native
+  });
+
+  /*
+    ForceDirected.Label.SVG
+    
+    Custom extension of <Graph.Label.SVG>.
+  
+    Extends:
+  
+    All <Graph.Label.SVG> methods
+  
+    See also:
+  
+    <Graph.Label.SVG>
+  
+  */
+  ForceDirected.Label.SVG = new Class( {
+    Implements: Graph.Label.SVG,
+
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+
+    /* 
+       placeLabel
+
+       Overrides abstract method placeLabel in <Graph.Label>.
+
+       Parameters:
+
+       tag - A DOM label element.
+       node - A <Graph.Node>.
+       controller - A configuration/controller object passed to the visualization.
+      
+     */
+    placeLabel: function(tag, node, controller) {
+      var pos = node.pos.getc(true), 
+          canvas = this.viz.canvas,
+          ox = canvas.translateOffsetX,
+          oy = canvas.translateOffsetY,
+          sx = canvas.scaleOffsetX,
+          sy = canvas.scaleOffsetY,
+          radius = canvas.getSize();
+      var labelPos = {
+        x: Math.round(pos.x * sx + ox + radius.width / 2),
+        y: Math.round(pos.y * sy + oy + radius.height / 2)
+      };
+      tag.setAttribute('x', labelPos.x);
+      tag.setAttribute('y', labelPos.y);
+
+      controller.onPlaceLabel(tag, node);
+    }
+  });
+
+  /*
+     ForceDirected.Label.HTML
+     
+     Custom extension of <Graph.Label.HTML>.
+
+     Extends:
+
+     All <Graph.Label.HTML> methods.
+
+     See also:
+
+     <Graph.Label.HTML>
+
+  */
+  ForceDirected.Label.HTML = new Class( {
+    Implements: Graph.Label.HTML,
+
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+    /* 
+       placeLabel
+
+       Overrides abstract method placeLabel in <Graph.Plot>.
+
+       Parameters:
+
+       tag - A DOM label element.
+       node - A <Graph.Node>.
+       controller - A configuration/controller object passed to the visualization.
+      
+     */
+    placeLabel: function(tag, node, controller) {
+      var pos = node.pos.getc(true), 
+          canvas = this.viz.canvas,
+          ox = canvas.translateOffsetX,
+          oy = canvas.translateOffsetY,
+          sx = canvas.scaleOffsetX,
+          sy = canvas.scaleOffsetY,
+          radius = canvas.getSize();
+      var labelPos = {
+        x: Math.round(pos.x * sx + ox + radius.width / 2),
+        y: Math.round(pos.y * sy + oy + radius.height / 2)
+      };
+      var style = tag.style;
+      style.left = labelPos.x + 'px';
+      style.top = labelPos.y + 'px';
+      style.display = this.fitsInCanvas(labelPos, canvas) ? '' : 'none';
+
+      controller.onPlaceLabel(tag, node);
+    }
+  });
+
+  /*
+    Class: ForceDirected.Plot.NodeTypes
+
+    This class contains a list of <Graph.Node> built-in types. 
+    Node types implemented are 'none', 'circle', 'triangle', 'rectangle', 'star', 'ellipse' and 'square'.
+
+    You can add your custom node types, customizing your visualization to the extreme.
+
+    Example:
+
+    (start code js)
+      ForceDirected.Plot.NodeTypes.implement({
+        'mySpecialType': {
+          'render': function(node, canvas) {
+            //print your custom node to canvas
+          },
+          //optional
+          'contains': function(node, pos) {
+            //return true if pos is inside the node or false otherwise
+          }
+        }
+      });
+    (end code)
+
+  */
+  ForceDirected.Plot.NodeTypes = new Class({
+    'none': {
+      'render': $.empty,
+      'contains': $.lambda(false)
+    },
+    'circle': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        this.nodeHelper.circle.render('fill', pos, dim, canvas);
+      },
+      'contains': function(node, pos){
+        var npos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        return this.nodeHelper.circle.contains(npos, pos, dim);
+      }
+    },
+    'ellipse': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            width = node.getData('width'), 
+            height = node.getData('height');
+        this.nodeHelper.ellipse.render('fill', pos, width, height, canvas);
+        },
+      'contains': function(node, pos){
+        var npos = node.pos.getc(true), 
+            width = node.getData('width'), 
+            height = node.getData('height');
+        return this.nodeHelper.ellipse.contains(npos, pos, width, height);
+      }
+    },
+    'square': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        this.nodeHelper.square.render('fill', pos, dim, canvas);
+      },
+      'contains': function(node, pos){
+        var npos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        return this.nodeHelper.square.contains(npos, pos, dim);
+      }
+    },
+    'rectangle': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            width = node.getData('width'), 
+            height = node.getData('height');
+        this.nodeHelper.rectangle.render('fill', pos, width, height, canvas);
+      },
+      'contains': function(node, pos){
+        var npos = node.pos.getc(true), 
+            width = node.getData('width'), 
+            height = node.getData('height');
+        return this.nodeHelper.rectangle.contains(npos, pos, width, height);
+      }
+    },
+    'triangle': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        this.nodeHelper.triangle.render('fill', pos, dim, canvas);
+      },
+      'contains': function(node, pos) {
+        var npos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        return this.nodeHelper.triangle.contains(npos, pos, dim);
+      }
+    },
+    'star': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true),
+            dim = node.getData('dim');
+        this.nodeHelper.star.render('fill', pos, dim, canvas);
+      },
+      'contains': function(node, pos) {
+        var npos = node.pos.getc(true),
+            dim = node.getData('dim');
+        return this.nodeHelper.star.contains(npos, pos, dim);
+      }
+    }
+  });
+
+  /*
+    Class: ForceDirected.Plot.EdgeTypes
+  
+    This class contains a list of <Graph.Adjacence> built-in types. 
+    Edge types implemented are 'none', 'line' and 'arrow'.
+  
+    You can add your custom edge types, customizing your visualization to the extreme.
+  
+    Example:
+  
+    (start code js)
+      ForceDirected.Plot.EdgeTypes.implement({
+        'mySpecialType': {
+          'render': function(adj, canvas) {
+            //print your custom edge to canvas
+          },
+          //optional
+          'contains': function(adj, pos) {
+            //return true if pos is inside the arc or false otherwise
+          }
+        }
+      });
+    (end code)
+  
+  */
+  ForceDirected.Plot.EdgeTypes = new Class({
+    'none': $.empty,
+    'line': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        this.edgeHelper.line.render(from, to, canvas);
+      },
+      'contains': function(adj, pos) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        return this.edgeHelper.line.contains(from, to, pos, this.edge.epsilon);
+      }
+    },
+    'arrow': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true),
+            dim = adj.getData('dim'),
+            direction = adj.data.$direction,
+            inv = (direction && direction.length>1 && direction[0] != adj.nodeFrom.id);
+        this.edgeHelper.arrow.render(from, to, dim, inv, canvas);
+      },
+      'contains': function(adj, pos) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        return this.edgeHelper.arrow.contains(from, to, pos, this.edge.epsilon);
+      }
+    }
+  });
+
+})($jit.ForceDirected);
+
+
+/*
+ * File: Treemap.js
+ *
+*/
+
+$jit.TM = {};
+
+var TM = $jit.TM;
+
+$jit.TM.$extend = true;
+
+/*
+  Class: TM.Base
+  
+  Abstract class providing base functionality for <TM.Squarified>, <TM.Strip> and <TM.SliceAndDice> visualizations.
+  
+  Implements:
+  
+  All <Loader> methods
+  
+  Constructor Options:
+  
+  Inherits options from
+  
+  - <Options.Canvas>
+  - <Options.Controller>
+  - <Options.Node>
+  - <Options.Edge>
+  - <Options.Label>
+  - <Options.Events>
+  - <Options.Tips>
+  - <Options.NodeStyles>
+  - <Options.Navigation>
+  
+  Additionally, there are other parameters and some default values changed
+
+  orientation - (string) Default's *h*. Whether to set horizontal or vertical layouts. Possible values are 'h' and 'v'.
+  titleHeight - (number) Default's *13*. The height of the title rectangle for inner (non-leaf) nodes.
+  offset - (number) Default's *2*. Boxes offset.
+  constrained - (boolean) Default's *false*. Whether to show the entire tree when loaded or just the number of levels specified by _levelsToShow_.
+  levelsToShow - (number) Default's *3*. The number of levels to show for a subtree. This number is relative to the selected node.
+  animate - (boolean) Default's *false*. Whether to animate transitions.
+  Node.type - Described in <Options.Node>. Default's *rectangle*.
+  duration - Described in <Options.Fx>. Default's *700*.
+  fps - Described in <Options.Fx>. Default's *45*.
+  
+  Instance Properties:
+  
+  canvas - Access a <Canvas> instance.
+  graph - Access a <Graph> instance.
+  op - Access a <TM.Op> instance.
+  fx - Access a <TM.Plot> instance.
+  labels - Access a <TM.Label> interface implementation.
+
+  Inspired by:
+  
+  Squarified Treemaps (Mark Bruls, Kees Huizing, and Jarke J. van Wijk) <http://www.win.tue.nl/~vanwijk/stm.pdf>
+  
+  Tree visualization with tree-maps: 2-d space-filling approach (Ben Shneiderman) <http://hcil.cs.umd.edu/trs/91-03/91-03.html>
+  
+   Note:
+   
+   This visualization was built and engineered from scratch, taking only the paper as inspiration, and only shares some features with the visualization described in the paper.
+
+*/
+TM.Base = {
+  layout: {
+    orientation: "h",
+    vertical: function(){
+      return this.orientation == "v";
+    },
+    horizontal: function(){
+      return this.orientation == "h";
+    },
+    change: function(){
+      this.orientation = this.vertical()? "h" : "v";
+    }
+  },
+
+  initialize: function(controller){
+    var config = {
+      orientation: "h",
+      titleHeight: 13,
+      offset: 2,
+      levelsToShow: 0,
+      constrained: false,
+      animate: false,
+      Node: {
+        type: 'rectangle',
+        overridable: true,
+        //we all know why this is not zero,
+        //right, Firefox?
+        width: 3,
+        height: 3,
+        color: '#444'
+      },
+      Label: {
+        textAlign: 'center',
+        textBaseline: 'top'
+      },
+      Edge: {
+        type: 'none'
+      },
+      duration: 700,
+      fps: 45
+    };
+
+    this.controller = this.config = $.merge(Options("Canvas", "Node", "Edge",
+        "Fx", "Controller", "Tips", "NodeStyles", "Events", "Navigation", "Label"), config, controller);
+    this.layout.orientation = this.config.orientation;
+
+    var canvasConfig = this.config;
+    if (canvasConfig.useCanvas) {
+      this.canvas = canvasConfig.useCanvas;
+      this.config.labelContainer = this.canvas.id + '-label';
+    } else {
+      if(canvasConfig.background) {
+        canvasConfig.background = $.merge({
+          type: 'Circles'
+        }, canvasConfig.background);
+      }
+      this.canvas = new Canvas(this, canvasConfig);
+      this.config.labelContainer = (typeof canvasConfig.injectInto == 'string'? canvasConfig.injectInto : canvasConfig.injectInto.id) + '-label';
+    }
+
+    this.graphOptions = {
+      'klass': Complex,
+      'Node': {
+        'selected': false,
+        'exist': true,
+        'drawn': true
+      }
+    };
+    this.graph = new Graph(this.graphOptions, this.config.Node,
+        this.config.Edge);
+    this.labels = new TM.Label[canvasConfig.Label.type](this);
+    this.fx = new TM.Plot(this);
+    this.op = new TM.Op(this);
+    this.group = new TM.Group(this);
+    this.geom = new TM.Geom(this);
+    this.clickedNode = null;
+    this.busy = false;
+    // initialize extras
+    this.initializeExtras();
+  },
+
+  /* 
+    Method: refresh 
+    
+    Computes positions and plots the tree.
+  */
+  refresh: function(){
+    if(this.busy) return;
+    this.busy = true;
+    var that = this;
+    if(this.config.animate) {
+      this.compute('end');
+      this.config.levelsToShow > 0 && this.geom.setRightLevelToShow(this.graph.getNode(this.clickedNode 
+          && this.clickedNode.id || this.root));
+      this.fx.animate($.merge(this.config, {
+        modes: ['linear', 'node-property:width:height'],
+        onComplete: function() {
+          that.busy = false;
+        }
+      }));
+    } else {
+      var labelType = this.config.Label.type;
+      if(labelType != 'Native') {
+        var that = this;
+        this.graph.eachNode(function(n) { that.labels.hideLabel(n, false); });
+      }
+      this.busy = false;
+      this.compute();
+      this.config.levelsToShow > 0 && this.geom.setRightLevelToShow(this.graph.getNode(this.clickedNode 
+          && this.clickedNode.id || this.root));
+      this.plot();
+    }
+  },
+
+  /* 
+    Method: plot 
+    
+    Plots the TreeMap. This is a shortcut to *fx.plot*. 
+  
+   */
+  plot: function(){
+    this.fx.plot();
+  },
+
+  /* 
+  Method: leaf 
+  
+  Returns whether the node is a leaf.
+  
+   Parameters:
+   
+   n - (object) A <Graph.Node>.
+
+ */
+  leaf: function(n){
+    return n.getSubnodes([
+        1, 1
+    ], "ignore").length == 0;
+  },
+  
+  /* 
+  Method: enter 
+  
+  Sets the node as root.
+  
+   Parameters:
+   
+   n - (object) A <Graph.Node>.
+
+ */
+  enter: function(n){
+    if(this.busy) return;
+    this.busy = true;
+    
+    var that = this,
+        config = this.config,
+        graph = this.graph,
+        clickedNode = n,
+        previousClickedNode = this.clickedNode;
+
+    var callback = {
+      onComplete: function() {
+        //ensure that nodes are shown for that level
+        if(config.levelsToShow > 0) {
+          that.geom.setRightLevelToShow(n);
+        }
+        //compute positions of newly inserted nodes
+        if(config.levelsToShow > 0 || config.request) that.compute();
+        if(config.animate) {
+          //fade nodes
+          graph.nodeList.setData('alpha', 0, 'end');
+          n.eachSubgraph(function(n) {
+            n.setData('alpha', 1, 'end');
+          }, "ignore");
+          that.fx.animate({
+            duration: 500,
+            modes:['node-property:alpha'],
+            onComplete: function() {
+              //compute end positions
+              that.clickedNode = clickedNode;
+              that.compute('end');
+              //animate positions
+              //TODO(nico) commenting this line didn't seem to throw errors...
+              that.clickedNode = previousClickedNode;
+              that.fx.animate({
+                modes:['linear', 'node-property:width:height'],
+                duration: 1000,
+                onComplete: function() { 
+                  that.busy = false;
+                  //TODO(nico) check comment above
+                  that.clickedNode = clickedNode;
+                }
+              });
+            }
+          });
+        } else {
+          that.busy = false;
+          that.clickedNode = n;
+          that.refresh();
+        }
+      }
+    };
+    if(config.request) {
+      this.requestNodes(clickedNode, callback);
+    } else {
+      callback.onComplete();
+    }
+  },
+
+  /* 
+  Method: out 
+  
+  Sets the parent node of the current selected node as root.
+
+ */
+  out: function(){
+    if(this.busy) return;
+    this.busy = true;
+    this.events.hoveredNode = false;
+    var that = this,
+        config = this.config,
+        graph = this.graph,
+        parents = graph.getNode(this.clickedNode 
+            && this.clickedNode.id || this.root).getParents(),
+        parent = parents[0],
+        clickedNode = parent,
+        previousClickedNode = this.clickedNode;
+    
+    //if no parents return
+    if(!parent) {
+      this.busy = false;
+      return;
+    }
+    //final plot callback
+    callback = {
+      onComplete: function() {
+        that.clickedNode = parent;
+        if(config.request) {
+          that.requestNodes(parent, {
+            onComplete: function() {
+              that.compute();
+              that.plot();
+              that.busy = false;
+            }
+          });
+        } else {
+          that.compute();
+          that.plot();
+          that.busy = false;
+        }
+      }
+    };
+    //prune tree
+    if (config.levelsToShow > 0)
+      this.geom.setRightLevelToShow(parent);
+    //animate node positions
+    if(config.animate) {
+      this.clickedNode = clickedNode;
+      this.compute('end');
+      //animate the visible subtree only
+      this.clickedNode = previousClickedNode;
+      this.fx.animate({
+        modes:['linear', 'node-property:width:height'],
+        duration: 1000,
+        onComplete: function() {
+          //animate the parent subtree
+          that.clickedNode = clickedNode;
+          //change nodes alpha
+          graph.eachNode(function(n) {
+            n.setDataset(['current', 'end'], {
+              'alpha': [0, 1]
+            });
+          }, "ignore");
+          previousClickedNode.eachSubgraph(function(node) {
+            node.setData('alpha', 1);
+          }, "ignore");
+          that.fx.animate({
+            duration: 500,
+            modes:['node-property:alpha'],
+            onComplete: function() {
+              callback.onComplete();
+            }
+          });
+        }
+      });
+    } else {
+      callback.onComplete();
+    }
+  },
+
+  requestNodes: function(node, onComplete){
+    var handler = $.merge(this.controller, onComplete), 
+        lev = this.config.levelsToShow;
+    if (handler.request) {
+      var leaves = [], d = node._depth;
+      node.eachLevel(0, lev, function(n){
+        var nodeLevel = lev - (n._depth - d);
+        if (n.drawn && !n.anySubnode() && nodeLevel > 0) {
+          leaves.push(n);
+          n._level = nodeLevel;
+        }
+      });
+      this.group.requestNodes(leaves, handler);
+    } else {
+      handler.onComplete();
+    }
+  },
+  
+  reposition: function() {
+    this.compute('end');
+  }
+};
+
+/*
+  Class: TM.Op
+  
+  Custom extension of <Graph.Op>.
+  
+  Extends:
+  
+  All <Graph.Op> methods
+  
+  See also:
+  
+  <Graph.Op>
+  
+  */
+TM.Op = new Class({
+  Implements: Graph.Op,
+
+  initialize: function(viz){
+    this.viz = viz;
+  }
+});
+
+//extend level methods of Graph.Geom
+TM.Geom = new Class({
+  Implements: Graph.Geom,
+  
+  getRightLevelToShow: function() {
+    return this.viz.config.levelsToShow;
+  },
+  
+  setRightLevelToShow: function(node) {
+    var level = this.getRightLevelToShow(), 
+        fx = this.viz.labels;
+    node.eachLevel(0, level+1, function(n) {
+      var d = n._depth - node._depth;
+      if(d > level) {
+        n.drawn = false; 
+        n.exist = false;
+        n.ignore = true;
+        fx.hideLabel(n, false);
+      } else {
+        n.drawn = true;
+        n.exist = true;
+        delete n.ignore;
+      }
+    });
+    node.drawn = true;
+    delete node.ignore;
+  }
+});
+
+/*
+
+Performs operations on group of nodes.
+
+*/
+TM.Group = new Class( {
+
+  initialize: function(viz){
+    this.viz = viz;
+    this.canvas = viz.canvas;
+    this.config = viz.config;
+  },
+
+  /*
+  
+    Calls the request method on the controller to request a subtree for each node. 
+  */
+  requestNodes: function(nodes, controller){
+    var counter = 0, len = nodes.length, nodeSelected = {};
+    var complete = function(){
+      controller.onComplete();
+    };
+    var viz = this.viz;
+    if (len == 0)
+      complete();
+    for ( var i = 0; i < len; i++) {
+      nodeSelected[nodes[i].id] = nodes[i];
+      controller.request(nodes[i].id, nodes[i]._level, {
+        onComplete: function(nodeId, data){
+          if (data && data.children) {
+            data.id = nodeId;
+            viz.op.sum(data, {
+              type: 'nothing'
+            });
+          }
+          if (++counter == len) {
+            viz.graph.computeLevels(viz.root, 0);
+            complete();
+          }
+        }
+      });
+    }
+  }
+});
+
+/*
+  Class: TM.Plot
+  
+  Custom extension of <Graph.Plot>.
+  
+  Extends:
+  
+  All <Graph.Plot> methods
+  
+  See also:
+  
+  <Graph.Plot>
+  
+  */
+TM.Plot = new Class({
+
+  Implements: Graph.Plot,
+
+  initialize: function(viz){
+    this.viz = viz;
+    this.config = viz.config;
+    this.node = this.config.Node;
+    this.edge = this.config.Edge;
+    this.animation = new Animation;
+    this.nodeTypes = new TM.Plot.NodeTypes;
+    this.edgeTypes = new TM.Plot.EdgeTypes;
+    this.labels = viz.labels;
+  },
+
+  plot: function(opt, animating){
+    var viz = this.viz, 
+        graph = viz.graph;
+    viz.canvas.clear();
+    this.plotTree(graph.getNode(viz.clickedNode && viz.clickedNode.id || viz.root), $.merge(viz.config, opt || {}, {
+      'withLabels': true,
+      'hideLabels': false,
+      'plotSubtree': function(n, ch){
+        return n.anySubnode("exist");
+      }
+    }), animating);
+  }
+});
+
+/*
+  Class: TM.Label
+  
+  Custom extension of <Graph.Label>. 
+  Contains custom <Graph.Label.SVG>, <Graph.Label.HTML> and <Graph.Label.Native> extensions.
+
+  Extends:
+
+  All <Graph.Label> methods and subclasses.
+
+  See also:
+
+  <Graph.Label>, <Graph.Label.Native>, <Graph.Label.HTML>, <Graph.Label.SVG>.
+  
+*/
+TM.Label = {};
+
+/*
+ TM.Label.Native
+
+ Custom extension of <Graph.Label.Native>.
+
+ Extends:
+
+ All <Graph.Label.Native> methods
+
+ See also:
+
+ <Graph.Label.Native>
+*/
+TM.Label.Native = new Class({
+  Implements: Graph.Label.Native,
+
+  initialize: function(viz) {
+    this.config = viz.config;
+    this.leaf = viz.leaf;
+  },
+  
+  renderLabel: function(canvas, node, controller){
+    if(!this.leaf(node) && !this.config.titleHeight) return;
+    var pos = node.pos.getc(true), 
+        ctx = canvas.getCtx(),
+        width = node.getData('width'),
+        height = node.getData('height'),
+        x = pos.x + width/2,
+        y = pos.y;
+        
+    ctx.fillText(node.name, x, y, width);
+  }
+});
+
+/*
+ TM.Label.SVG
+
+  Custom extension of <Graph.Label.SVG>.
+
+  Extends:
+
+  All <Graph.Label.SVG> methods
+
+  See also:
+
+  <Graph.Label.SVG>
+*/
+TM.Label.SVG = new Class( {
+  Implements: Graph.Label.SVG,
+
+  initialize: function(viz){
+    this.viz = viz;
+    this.leaf = viz.leaf;
+    this.config = viz.config;
+  },
+
+  /* 
+  placeLabel
+
+  Overrides abstract method placeLabel in <Graph.Plot>.
+
+  Parameters:
+
+  tag - A DOM label element.
+  node - A <Graph.Node>.
+  controller - A configuration/controller object passed to the visualization.
+  
+  */
+  placeLabel: function(tag, node, controller){
+    var pos = node.pos.getc(true), 
+        canvas = this.viz.canvas,
+        ox = canvas.translateOffsetX,
+        oy = canvas.translateOffsetY,
+        sx = canvas.scaleOffsetX,
+        sy = canvas.scaleOffsetY,
+        radius = canvas.getSize();
+    var labelPos = {
+      x: Math.round(pos.x * sx + ox + radius.width / 2),
+      y: Math.round(pos.y * sy + oy + radius.height / 2)
+    };
+    tag.setAttribute('x', labelPos.x);
+    tag.setAttribute('y', labelPos.y);
+
+    if(!this.leaf(node) && !this.config.titleHeight) {
+      tag.style.display = 'none';
+    }
+    controller.onPlaceLabel(tag, node);
+  }
+});
+
+/*
+ TM.Label.HTML
+
+ Custom extension of <Graph.Label.HTML>.
+
+ Extends:
+
+ All <Graph.Label.HTML> methods.
+
+ See also:
+
+ <Graph.Label.HTML>
+
+*/
+TM.Label.HTML = new Class( {
+  Implements: Graph.Label.HTML,
+
+  initialize: function(viz){
+    this.viz = viz;
+    this.leaf = viz.leaf;
+    this.config = viz.config;
+  },
+
+  /* 
+    placeLabel
+  
+    Overrides abstract method placeLabel in <Graph.Plot>.
+  
+    Parameters:
+  
+    tag - A DOM label element.
+    node - A <Graph.Node>.
+    controller - A configuration/controller object passed to the visualization.
+  
+  */
+  placeLabel: function(tag, node, controller){
+    var pos = node.pos.getc(true), 
+        canvas = this.viz.canvas,
+        ox = canvas.translateOffsetX,
+        oy = canvas.translateOffsetY,
+        sx = canvas.scaleOffsetX,
+        sy = canvas.scaleOffsetY,
+        radius = canvas.getSize();
+    var labelPos = {
+      x: Math.round(pos.x * sx + ox + radius.width / 2),
+      y: Math.round(pos.y * sy + oy + radius.height / 2)
+    };
+
+    var style = tag.style;
+    style.left = labelPos.x + 'px';
+    style.top = labelPos.y + 'px';
+    style.width = node.getData('width') * sx + 'px';
+    style.height = node.getData('height') * sy + 'px';
+    style.zIndex = node._depth * 100;
+    style.display = '';
+
+    if(!this.leaf(node) && !this.config.titleHeight) {
+      tag.style.display = 'none';
+    }
+    controller.onPlaceLabel(tag, node);
+  }
+});
+
+/*
+  Class: TM.Plot.NodeTypes
+
+  This class contains a list of <Graph.Node> built-in types. 
+  Node types implemented are 'none', 'rectangle'.
+
+  You can add your custom node types, customizing your visualization to the extreme.
+
+  Example:
+
+  (start code js)
+    TM.Plot.NodeTypes.implement({
+      'mySpecialType': {
+        'render': function(node, canvas) {
+          //print your custom node to canvas
+        },
+        //optional
+        'contains': function(node, pos) {
+          //return true if pos is inside the node or false otherwise
+        }
+      }
+    });
+  (end code)
+
+*/
+TM.Plot.NodeTypes = new Class( {
+  'none': {
+    'render': $.empty
+  },
+
+  'rectangle': {
+    'render': function(node, canvas, animating){
+      var leaf = this.viz.leaf(node),
+          config = this.config,
+          offst = config.offset,
+          titleHeight = config.titleHeight,
+          pos = node.pos.getc(true),
+          width = node.getData('width'),
+          height = node.getData('height'),
+          border = node.getData('border'),
+          ctx = canvas.getCtx(),
+          posx = pos.x + offst / 2, 
+          posy = pos.y + offst / 2;
+      if(width <= offst || height <= offst) return;
+      if (leaf) {
+        if(config.cushion) {
+          var lg = ctx.createRadialGradient(posx + (width-offst)/2, posy + (height-offst)/2, 1, 
+              posx + (width-offst)/2, posy + (height-offst)/2, width < height? height : width);
+          var color = node.getData('color');
+          var colorGrad = $.rgbToHex($.map($.hexToRgb(color), 
+              function(r) { return r * 0.2 >> 0; }));
+          lg.addColorStop(0, color);
+          lg.addColorStop(1, colorGrad);
+          ctx.fillStyle = lg;
+        }
+        ctx.fillRect(posx, posy, width - offst, height - offst);
+        if(border) {
+          ctx.save();
+          ctx.strokeStyle = border;
+          ctx.strokeRect(posx, posy, width - offst, height - offst);
+          ctx.restore();
+        }
+      } else if(titleHeight > 0){
+        ctx.fillRect(pos.x + offst / 2, pos.y + offst / 2, width - offst,
+            titleHeight - offst);
+        if(border) {
+          ctx.save();
+          ctx.strokeStyle = border;
+          ctx.strokeRect(pos.x + offst / 2, pos.y + offst / 2, width - offst,
+              height - offst);
+          ctx.restore();
+        }
+      }
+    },
+    'contains': function(node, pos) {
+      if(this.viz.clickedNode && !node.isDescendantOf(this.viz.clickedNode.id) || node.ignore) return false;
+      var npos = node.pos.getc(true),
+          width = node.getData('width'), 
+          leaf = this.viz.leaf(node),
+          height = leaf? node.getData('height') : this.config.titleHeight;
+      return this.nodeHelper.rectangle.contains({x: npos.x + width/2, y: npos.y + height/2}, pos, width, height);
+    }
+  }
+});
+
+TM.Plot.EdgeTypes = new Class( {
+  'none': $.empty
+});
+
+/*
+  Class: TM.SliceAndDice
+  
+  A slice and dice TreeMap visualization.
+  
+  Implements:
+  
+  All <TM.Base> methods and properties.
+*/
+TM.SliceAndDice = new Class( {
+  Implements: [
+      Loader, Extras, TM.Base, Layouts.TM.SliceAndDice
+  ]
+});
+
+/*
+  Class: TM.Squarified
+  
+  A squarified TreeMap visualization.
+
+  Implements:
+  
+  All <TM.Base> methods and properties.
+*/
+TM.Squarified = new Class( {
+  Implements: [
+      Loader, Extras, TM.Base, Layouts.TM.Squarified
+  ]
+});
+
+/*
+  Class: TM.Strip
+  
+  A strip TreeMap visualization.
+
+  Implements:
+  
+  All <TM.Base> methods and properties.
+*/
+TM.Strip = new Class( {
+  Implements: [
+      Loader, Extras, TM.Base, Layouts.TM.Strip
+  ]
+});
+
+
+/*
+ * File: RGraph.js
+ *
+ */
+
+/*
+   Class: RGraph
+   
+   A radial graph visualization with advanced animations.
+   
+   Inspired by:
+ 
+   Animated Exploration of Dynamic Graphs with Radial Layout (Ka-Ping Yee, Danyel Fisher, Rachna Dhamija, Marti Hearst) <http://bailando.sims.berkeley.edu/papers/infovis01.htm>
+   
+   Note:
+   
+   This visualization was built and engineered from scratch, taking only the paper as inspiration, and only shares some features with the visualization described in the paper.
+   
+  Implements:
+  
+  All <Loader> methods
+  
+   Constructor Options:
+   
+   Inherits options from
+   
+   - <Options.Canvas>
+   - <Options.Controller>
+   - <Options.Node>
+   - <Options.Edge>
+   - <Options.Label>
+   - <Options.Events>
+   - <Options.Tips>
+   - <Options.NodeStyles>
+   - <Options.Navigation>
+   
+   Additionally, there are other parameters and some default values changed
+   
+   interpolation - (string) Default's *linear*. Describes the way nodes are interpolated. Possible values are 'linear' and 'polar'.
+   levelDistance - (number) Default's *100*. The distance between levels of the tree. 
+     
+   Instance Properties:
+
+   canvas - Access a <Canvas> instance.
+   graph - Access a <Graph> instance.
+   op - Access a <RGraph.Op> instance.
+   fx - Access a <RGraph.Plot> instance.
+   labels - Access a <RGraph.Label> interface implementation.   
+*/
+
+$jit.RGraph = new Class( {
+
+  Implements: [
+      Loader, Extras, Layouts.Radial
+  ],
+
+  initialize: function(controller){
+    var $RGraph = $jit.RGraph;
+
+    var config = {
+      interpolation: 'linear',
+      levelDistance: 100
+    };
+
+    this.controller = this.config = $.merge(Options("Canvas", "Node", "Edge",
+        "Fx", "Controller", "Tips", "NodeStyles", "Events", "Navigation", "Label"), config, controller);
+
+    var canvasConfig = this.config;
+    if(canvasConfig.useCanvas) {
+      this.canvas = canvasConfig.useCanvas;
+      this.config.labelContainer = this.canvas.id + '-label';
+    } else {
+      if(canvasConfig.background) {
+        canvasConfig.background = $.merge({
+          type: 'Circles'
+        }, canvasConfig.background);
+      }
+      this.canvas = new Canvas(this, canvasConfig);
+      this.config.labelContainer = (typeof canvasConfig.injectInto == 'string'? canvasConfig.injectInto : canvasConfig.injectInto.id) + '-label';
+    }
+
+    this.graphOptions = {
+      'klass': Polar,
+      'Node': {
+        'selected': false,
+        'exist': true,
+        'drawn': true
+      }
+    };
+    this.graph = new Graph(this.graphOptions, this.config.Node,
+        this.config.Edge);
+    this.labels = new $RGraph.Label[canvasConfig.Label.type](this);
+    this.fx = new $RGraph.Plot(this, $RGraph);
+    this.op = new $RGraph.Op(this);
+    this.json = null;
+    this.root = null;
+    this.busy = false;
+    this.parent = false;
+    // initialize extras
+    this.initializeExtras();
+  },
+
+  /* 
+  
+    createLevelDistanceFunc 
+  
+    Returns the levelDistance function used for calculating a node distance 
+    to its origin. This function returns a function that is computed 
+    per level and not per node, such that all nodes with the same depth will have the 
+    same distance to the origin. The resulting function gets the 
+    parent node as parameter and returns a float.
+
+   */
+  createLevelDistanceFunc: function(){
+    var ld = this.config.levelDistance;
+    return function(elem){
+      return (elem._depth + 1) * ld;
+    };
+  },
+
+  /* 
+     Method: refresh 
+     
+     Computes positions and plots the tree.
+
+   */
+  refresh: function(){
+    this.compute();
+    this.plot();
+  },
+
+  reposition: function(){
+    this.compute('end');
+  },
+
+  /*
+   Method: plot
+  
+   Plots the RGraph. This is a shortcut to *fx.plot*.
+  */
+  plot: function(){
+    this.fx.plot();
+  },
+  /*
+   getNodeAndParentAngle
+  
+   Returns the _parent_ of the given node, also calculating its angle span.
+  */
+  getNodeAndParentAngle: function(id){
+    var theta = false;
+    var n = this.graph.getNode(id);
+    var ps = n.getParents();
+    var p = (ps.length > 0)? ps[0] : false;
+    if (p) {
+      var posParent = p.pos.getc(), posChild = n.pos.getc();
+      var newPos = posParent.add(posChild.scale(-1));
+      theta = Math.atan2(newPos.y, newPos.x);
+      if (theta < 0)
+        theta += 2 * Math.PI;
+    }
+    return {
+      parent: p,
+      theta: theta
+    };
+  },
+  /*
+   tagChildren
+  
+   Enumerates the children in order to maintain child ordering (second constraint of the paper).
+  */
+  tagChildren: function(par, id){
+    if (par.angleSpan) {
+      var adjs = [];
+      par.eachAdjacency(function(elem){
+        adjs.push(elem.nodeTo);
+      }, "ignore");
+      var len = adjs.length;
+      for ( var i = 0; i < len && id != adjs[i].id; i++)
+        ;
+      for ( var j = (i + 1) % len, k = 0; id != adjs[j].id; j = (j + 1) % len) {
+        adjs[j].dist = k++;
+      }
+    }
+  },
+  /* 
+  Method: onClick 
+  
+  Animates the <RGraph> to center the node specified by *id*.
+
+   Parameters:
+
+   id - A <Graph.Node> id.
+   opt - (optional|object) An object containing some extra properties described below
+   hideLabels - (boolean) Default's *true*. Hide labels when performing the animation.
+
+   Example:
+
+   (start code js)
+     rgraph.onClick('someid');
+     //or also...
+     rgraph.onClick('someid', {
+      hideLabels: false
+     });
+    (end code)
+    
+  */
+  onClick: function(id, opt){
+    if (this.root != id && !this.busy) {
+      this.busy = true;
+      this.root = id;
+      var that = this;
+      this.controller.onBeforeCompute(this.graph.getNode(id));
+      var obj = this.getNodeAndParentAngle(id);
+
+      // second constraint
+      this.tagChildren(obj.parent, id);
+      this.parent = obj.parent;
+      this.compute('end');
+
+      // first constraint
+      var thetaDiff = obj.theta - obj.parent.endPos.theta;
+      this.graph.eachNode(function(elem){
+        elem.endPos.set(elem.endPos.getp().add($P(thetaDiff, 0)));
+      });
+
+      var mode = this.config.interpolation;
+      opt = $.merge( {
+        onComplete: $.empty
+      }, opt || {});
+
+      this.fx.animate($.merge( {
+        hideLabels: true,
+        modes: [
+          mode
+        ]
+      }, opt, {
+        onComplete: function(){
+          that.busy = false;
+          opt.onComplete();
+        }
+      }));
+    }
+  }
+});
+
+$jit.RGraph.$extend = true;
+
+(function(RGraph){
+
+  /*
+     Class: RGraph.Op
+     
+     Custom extension of <Graph.Op>.
+
+     Extends:
+
+     All <Graph.Op> methods
+     
+     See also:
+     
+     <Graph.Op>
+
+  */
+  RGraph.Op = new Class( {
+
+    Implements: Graph.Op
+
+  });
+
+  /*
+     Class: RGraph.Plot
+    
+    Custom extension of <Graph.Plot>.
+  
+    Extends:
+  
+    All <Graph.Plot> methods
+    
+    See also:
+    
+    <Graph.Plot>
+  
+  */
+  RGraph.Plot = new Class( {
+
+    Implements: Graph.Plot
+
+  });
+
+  /*
+    Object: RGraph.Label
+
+    Custom extension of <Graph.Label>. 
+    Contains custom <Graph.Label.SVG>, <Graph.Label.HTML> and <Graph.Label.Native> extensions.
+  
+    Extends:
+  
+    All <Graph.Label> methods and subclasses.
+  
+    See also:
+  
+    <Graph.Label>, <Graph.Label.Native>, <Graph.Label.HTML>, <Graph.Label.SVG>.
+  
+   */
+  RGraph.Label = {};
+
+  /*
+     RGraph.Label.Native
+
+     Custom extension of <Graph.Label.Native>.
+
+     Extends:
+
+     All <Graph.Label.Native> methods
+
+     See also:
+
+     <Graph.Label.Native>
+
+  */
+  RGraph.Label.Native = new Class( {
+    Implements: Graph.Label.Native
+  });
+
+  /*
+     RGraph.Label.SVG
+    
+    Custom extension of <Graph.Label.SVG>.
+  
+    Extends:
+  
+    All <Graph.Label.SVG> methods
+  
+    See also:
+  
+    <Graph.Label.SVG>
+  
+  */
+  RGraph.Label.SVG = new Class( {
+    Implements: Graph.Label.SVG,
+
+    initialize: function(viz){
+      this.viz = viz;
+    },
+
+    /* 
+       placeLabel
+
+       Overrides abstract method placeLabel in <Graph.Plot>.
+
+       Parameters:
+
+       tag - A DOM label element.
+       node - A <Graph.Node>.
+       controller - A configuration/controller object passed to the visualization.
+      
+     */
+    placeLabel: function(tag, node, controller){
+      var pos = node.pos.getc(true), 
+          canvas = this.viz.canvas,
+          ox = canvas.translateOffsetX,
+          oy = canvas.translateOffsetY,
+          sx = canvas.scaleOffsetX,
+          sy = canvas.scaleOffsetY,
+          radius = canvas.getSize();
+      var labelPos = {
+        x: Math.round(pos.x * sx + ox + radius.width / 2),
+        y: Math.round(pos.y * sy + oy + radius.height / 2)
+      };
+      tag.setAttribute('x', labelPos.x);
+      tag.setAttribute('y', labelPos.y);
+
+      controller.onPlaceLabel(tag, node);
+    }
+  });
+
+  /*
+     RGraph.Label.HTML
+
+     Custom extension of <Graph.Label.HTML>.
+
+     Extends:
+
+     All <Graph.Label.HTML> methods.
+
+     See also:
+
+     <Graph.Label.HTML>
+
+  */
+  RGraph.Label.HTML = new Class( {
+    Implements: Graph.Label.HTML,
+
+    initialize: function(viz){
+      this.viz = viz;
+    },
+    /* 
+       placeLabel
+
+       Overrides abstract method placeLabel in <Graph.Plot>.
+
+       Parameters:
+
+       tag - A DOM label element.
+       node - A <Graph.Node>.
+       controller - A configuration/controller object passed to the visualization.
+      
+     */
+    placeLabel: function(tag, node, controller){
+      var pos = node.pos.getc(true), 
+          canvas = this.viz.canvas,
+          ox = canvas.translateOffsetX,
+          oy = canvas.translateOffsetY,
+          sx = canvas.scaleOffsetX,
+          sy = canvas.scaleOffsetY,
+          radius = canvas.getSize();
+      var labelPos = {
+        x: Math.round(pos.x * sx + ox + radius.width / 2),
+        y: Math.round(pos.y * sy + oy + radius.height / 2)
+      };
+
+      var style = tag.style;
+      style.left = labelPos.x + 'px';
+      style.top = labelPos.y + 'px';
+      style.display = this.fitsInCanvas(labelPos, canvas)? '' : 'none';
+
+      controller.onPlaceLabel(tag, node);
+    }
+  });
+
+  /*
+    Class: RGraph.Plot.NodeTypes
+
+    This class contains a list of <Graph.Node> built-in types. 
+    Node types implemented are 'none', 'circle', 'triangle', 'rectangle', 'star', 'ellipse' and 'square'.
+
+    You can add your custom node types, customizing your visualization to the extreme.
+
+    Example:
+
+    (start code js)
+      RGraph.Plot.NodeTypes.implement({
+        'mySpecialType': {
+          'render': function(node, canvas) {
+            //print your custom node to canvas
+          },
+          //optional
+          'contains': function(node, pos) {
+            //return true if pos is inside the node or false otherwise
+          }
+        }
+      });
+    (end code)
+
+  */
+  RGraph.Plot.NodeTypes = new Class({
+    'none': {
+      'render': $.empty,
+      'contains': $.lambda(false)
+    },
+    'circle': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        this.nodeHelper.circle.render('fill', pos, dim, canvas);
+      },
+      'contains': function(node, pos){
+        var npos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        return this.nodeHelper.circle.contains(npos, pos, dim);
+      }
+    },
+    'ellipse': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            width = node.getData('width'), 
+            height = node.getData('height');
+        this.nodeHelper.ellipse.render('fill', pos, width, height, canvas);
+        },
+      'contains': function(node, pos){
+        var npos = node.pos.getc(true), 
+            width = node.getData('width'), 
+            height = node.getData('height');
+        return this.nodeHelper.ellipse.contains(npos, pos, width, height);
+      }
+    },
+    'square': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        this.nodeHelper.square.render('fill', pos, dim, canvas);
+      },
+      'contains': function(node, pos){
+        var npos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        return this.nodeHelper.square.contains(npos, pos, dim);
+      }
+    },
+    'rectangle': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            width = node.getData('width'), 
+            height = node.getData('height');
+        this.nodeHelper.rectangle.render('fill', pos, width, height, canvas);
+      },
+      'contains': function(node, pos){
+        var npos = node.pos.getc(true), 
+            width = node.getData('width'), 
+            height = node.getData('height');
+        return this.nodeHelper.rectangle.contains(npos, pos, width, height);
+      }
+    },
+    'triangle': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        this.nodeHelper.triangle.render('fill', pos, dim, canvas);
+      },
+      'contains': function(node, pos) {
+        var npos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        return this.nodeHelper.triangle.contains(npos, pos, dim);
+      }
+    },
+    'star': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true),
+            dim = node.getData('dim');
+        this.nodeHelper.star.render('fill', pos, dim, canvas);
+      },
+      'contains': function(node, pos) {
+        var npos = node.pos.getc(true),
+            dim = node.getData('dim');
+        return this.nodeHelper.star.contains(npos, pos, dim);
+      }
+    }
+  });
+
+  /*
+    Class: RGraph.Plot.EdgeTypes
+
+    This class contains a list of <Graph.Adjacence> built-in types. 
+    Edge types implemented are 'none', 'line' and 'arrow'.
+  
+    You can add your custom edge types, customizing your visualization to the extreme.
+  
+    Example:
+  
+    (start code js)
+      RGraph.Plot.EdgeTypes.implement({
+        'mySpecialType': {
+          'render': function(adj, canvas) {
+            //print your custom edge to canvas
+          },
+          //optional
+          'contains': function(adj, pos) {
+            //return true if pos is inside the arc or false otherwise
+          }
+        }
+      });
+    (end code)
+  
+  */
+  RGraph.Plot.EdgeTypes = new Class({
+    'none': $.empty,
+    'line': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        this.edgeHelper.line.render(from, to, canvas);
+      },
+      'contains': function(adj, pos) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        return this.edgeHelper.line.contains(from, to, pos, this.edge.epsilon);
+      }
+    },
+    'arrow': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true),
+            dim = adj.getData('dim'),
+            direction = adj.data.$direction,
+            inv = (direction && direction.length>1 && direction[0] != adj.nodeFrom.id);
+        this.edgeHelper.arrow.render(from, to, dim, inv, canvas);
+      },
+      'contains': function(adj, pos) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        return this.edgeHelper.arrow.contains(from, to, pos, this.edge.epsilon);
+      }
+    }
+  });
+
+})($jit.RGraph);
+
+
+/*
+ * File: Hypertree.js
+ * 
+*/
+
+/* 
+     Complex 
+     
+     A multi-purpose Complex Class with common methods. Extended for the Hypertree. 
+ 
+*/
+/* 
+   moebiusTransformation 
+ 
+   Calculates a moebius transformation for this point / complex. 
+    For more information go to: 
+        http://en.wikipedia.org/wiki/Moebius_transformation. 
+ 
+   Parameters: 
+ 
+      c - An initialized Complex instance representing a translation Vector. 
+*/
+
+Complex.prototype.moebiusTransformation = function(c) {
+  var num = this.add(c);
+  var den = c.$conjugate().$prod(this);
+  den.x++;
+  return num.$div(den);
+};
+
+/* 
+    moebiusTransformation 
+     
+    Calculates a moebius transformation for the hyperbolic tree. 
+     
+    <http://en.wikipedia.org/wiki/Moebius_transformation> 
+      
+     Parameters: 
+     
+        graph - A <Graph> instance.
+        pos - A <Complex>.
+        prop - A property array.
+        theta - Rotation angle. 
+        startPos - _optional_ start position. 
+*/
+Graph.Util.moebiusTransformation = function(graph, pos, prop, startPos, flags) {
+  this.eachNode(graph, function(elem) {
+    for ( var i = 0; i < prop.length; i++) {
+      var p = pos[i].scale(-1), property = startPos ? startPos : prop[i];
+      elem.getPos(prop[i]).set(elem.getPos(property).getc().moebiusTransformation(p));
+    }
+  }, flags);
+};
+
+/* 
+   Class: Hypertree 
+   
+   A Hyperbolic Tree/Graph visualization.
+   
+   Inspired by:
+ 
+   A Focus+Context Technique Based on Hyperbolic Geometry for Visualizing Large Hierarchies (John Lamping, Ramana Rao, and Peter Pirolli). 
+   <http://www.cs.tau.ac.il/~asharf/shrek/Projects/HypBrowser/startree-chi95.pdf>
+ 
+  Note:
+ 
+  This visualization was built and engineered from scratch, taking only the paper as inspiration, and only shares some features with the Hypertree described in the paper.
+
+  Implements:
+  
+  All <Loader> methods
+  
+  Constructor Options:
+  
+  Inherits options from
+  
+  - <Options.Canvas>
+  - <Options.Controller>
+  - <Options.Node>
+  - <Options.Edge>
+  - <Options.Label>
+  - <Options.Events>
+  - <Options.Tips>
+  - <Options.NodeStyles>
+  - <Options.Navigation>
+  
+  Additionally, there are other parameters and some default values changed
+  
+  radius - (string|number) Default's *auto*. The radius of the disc to plot the <Hypertree> in. 'auto' will take the smaller value from the width and height canvas dimensions. You can also set this to a custom value, for example *250*.
+  offset - (number) Default's *0*. A number in the range [0, 1) that will be substracted to each node position to make a more compact <Hypertree>. This will avoid placing nodes too far from each other when a there's a selected node.
+  fps - Described in <Options.Fx>. It's default value has been changed to *35*.
+  duration - Described in <Options.Fx>. It's default value has been changed to *1500*.
+  Edge.type - Described in <Options.Edge>. It's default value has been changed to *hyperline*. 
+  
+  Instance Properties:
+  
+  canvas - Access a <Canvas> instance.
+  graph - Access a <Graph> instance.
+  op - Access a <Hypertree.Op> instance.
+  fx - Access a <Hypertree.Plot> instance.
+  labels - Access a <Hypertree.Label> interface implementation.
+
+*/
+
+$jit.Hypertree = new Class( {
+
+  Implements: [ Loader, Extras, Layouts.Radial ],
+
+  initialize: function(controller) {
+    var $Hypertree = $jit.Hypertree;
+
+    var config = {
+      radius: "auto",
+      offset: 0,
+      Edge: {
+        type: 'hyperline'
+      },
+      duration: 1500,
+      fps: 35
+    };
+    this.controller = this.config = $.merge(Options("Canvas", "Node", "Edge",
+        "Fx", "Tips", "NodeStyles", "Events", "Navigation", "Controller", "Label"), config, controller);
+
+    var canvasConfig = this.config;
+    if(canvasConfig.useCanvas) {
+      this.canvas = canvasConfig.useCanvas;
+      this.config.labelContainer = this.canvas.id + '-label';
+    } else {
+      if(canvasConfig.background) {
+        canvasConfig.background = $.merge({
+          type: 'Circles'
+        }, canvasConfig.background);
+      }
+      this.canvas = new Canvas(this, canvasConfig);
+      this.config.labelContainer = (typeof canvasConfig.injectInto == 'string'? canvasConfig.injectInto : canvasConfig.injectInto.id) + '-label';
+    }
+
+    this.graphOptions = {
+      'klass': Polar,
+      'Node': {
+        'selected': false,
+        'exist': true,
+        'drawn': true
+      }
+    };
+    this.graph = new Graph(this.graphOptions, this.config.Node,
+        this.config.Edge);
+    this.labels = new $Hypertree.Label[canvasConfig.Label.type](this);
+    this.fx = new $Hypertree.Plot(this, $Hypertree);
+    this.op = new $Hypertree.Op(this);
+    this.json = null;
+    this.root = null;
+    this.busy = false;
+    // initialize extras
+    this.initializeExtras();
+  },
+
+  /* 
+  
+  createLevelDistanceFunc 
+
+  Returns the levelDistance function used for calculating a node distance 
+  to its origin. This function returns a function that is computed 
+  per level and not per node, such that all nodes with the same depth will have the 
+  same distance to the origin. The resulting function gets the 
+  parent node as parameter and returns a float.
+
+  */
+  createLevelDistanceFunc: function() {
+    // get max viz. length.
+    var r = this.getRadius();
+    // get max depth.
+    var depth = 0, max = Math.max, config = this.config;
+    this.graph.eachNode(function(node) {
+      depth = max(node._depth, depth);
+    }, "ignore");
+    depth++;
+    // node distance generator
+    var genDistFunc = function(a) {
+      return function(node) {
+        node.scale = r;
+        var d = node._depth + 1;
+        var acum = 0, pow = Math.pow;
+        while (d) {
+          acum += pow(a, d--);
+        }
+        return acum - config.offset;
+      };
+    };
+    // estimate better edge length.
+    for ( var i = 0.51; i <= 1; i += 0.01) {
+      var valSeries = (1 - Math.pow(i, depth)) / (1 - i);
+      if (valSeries >= 2) { return genDistFunc(i - 0.01); }
+    }
+    return genDistFunc(0.75);
+  },
+
+  /* 
+    Method: getRadius 
+    
+    Returns the current radius of the visualization. If *config.radius* is *auto* then it 
+    calculates the radius by taking the smaller size of the <Canvas> widget.
+    
+    See also:
+    
+    <Canvas.getSize>
+   
+  */
+  getRadius: function() {
+    var rad = this.config.radius;
+    if (rad !== "auto") { return rad; }
+    var s = this.canvas.getSize();
+    return Math.min(s.width, s.height) / 2;
+  },
+
+  /* 
+    Method: refresh 
+    
+    Computes positions and plots the tree.
+
+    Parameters:
+
+    reposition - (optional|boolean) Set this to *true* to force all positions (current, start, end) to match.
+
+   */
+  refresh: function(reposition) {
+    if (reposition) {
+      this.reposition();
+      this.graph.eachNode(function(node) {
+        node.startPos.rho = node.pos.rho = node.endPos.rho;
+        node.startPos.theta = node.pos.theta = node.endPos.theta;
+      });
+    } else {
+      this.compute();
+    }
+    this.plot();
+  },
+
+  /* 
+   reposition 
+   
+   Computes nodes' positions and restores the tree to its previous position.
+
+   For calculating nodes' positions the root must be placed on its origin. This method does this 
+     and then attemps to restore the hypertree to its previous position.
+    
+  */
+  reposition: function() {
+    this.compute('end');
+    var vector = this.graph.getNode(this.root).pos.getc().scale(-1);
+    Graph.Util.moebiusTransformation(this.graph, [ vector ], [ 'end' ],
+        'end', "ignore");
+    this.graph.eachNode(function(node) {
+      if (node.ignore) {
+        node.endPos.rho = node.pos.rho;
+        node.endPos.theta = node.pos.theta;
+      }
+    });
+  },
+
+  /* 
+   Method: plot 
+   
+   Plots the <Hypertree>. This is a shortcut to *fx.plot*. 
+
+  */
+  plot: function() {
+    this.fx.plot();
+  },
+
+  /* 
+   Method: onClick 
+   
+   Animates the <Hypertree> to center the node specified by *id*.
+
+   Parameters:
+
+   id - A <Graph.Node> id.
+   opt - (optional|object) An object containing some extra properties described below
+   hideLabels - (boolean) Default's *true*. Hide labels when performing the animation.
+
+   Example:
+
+   (start code js)
+     ht.onClick('someid');
+     //or also...
+     ht.onClick('someid', {
+      hideLabels: false
+     });
+    (end code)
+    
+  */
+  onClick: function(id, opt) {
+    var pos = this.graph.getNode(id).pos.getc(true);
+    this.move(pos, opt);
+  },
+
+  /* 
+   Method: move 
+
+   Translates the tree to the given position. 
+
+   Parameters:
+
+   pos - (object) A *x, y* coordinate object where x, y in [0, 1), to move the tree to.
+   opt - This object has been defined in <Hypertree.onClick>
+   
+   Example:
+   
+   (start code js)
+     ht.move({ x: 0, y: 0.7 }, {
+       hideLabels: false
+     });
+   (end code)
+
+  */
+  move: function(pos, opt) {
+    var versor = $C(pos.x, pos.y);
+    if (this.busy === false && versor.norm() < 1) {
+      this.busy = true;
+      var root = this.graph.getClosestNodeToPos(versor), that = this;
+      this.graph.computeLevels(root.id, 0);
+      this.controller.onBeforeCompute(root);
+      opt = $.merge( {
+        onComplete: $.empty
+      }, opt || {});
+      this.fx.animate($.merge( {
+        modes: [ 'moebius' ],
+        hideLabels: true
+      }, opt, {
+        onComplete: function() {
+          that.busy = false;
+          opt.onComplete();
+        }
+      }), versor);
+    }
+  }
+});
+
+$jit.Hypertree.$extend = true;
+
+(function(Hypertree) {
+
+  /* 
+     Class: Hypertree.Op 
+   
+     Custom extension of <Graph.Op>.
+
+     Extends:
+
+     All <Graph.Op> methods
+     
+     See also:
+     
+     <Graph.Op>
+
+  */
+  Hypertree.Op = new Class( {
+
+    Implements: Graph.Op
+
+  });
+
+  /* 
+     Class: Hypertree.Plot 
+   
+    Custom extension of <Graph.Plot>.
+  
+    Extends:
+  
+    All <Graph.Plot> methods
+    
+    See also:
+    
+    <Graph.Plot>
+  
+  */
+  Hypertree.Plot = new Class( {
+
+    Implements: Graph.Plot
+
+  });
+
+  /*
+    Object: Hypertree.Label
+
+    Custom extension of <Graph.Label>. 
+    Contains custom <Graph.Label.SVG>, <Graph.Label.HTML> and <Graph.Label.Native> extensions.
+  
+    Extends:
+  
+    All <Graph.Label> methods and subclasses.
+  
+    See also:
+  
+    <Graph.Label>, <Graph.Label.Native>, <Graph.Label.HTML>, <Graph.Label.SVG>.
+
+   */
+  Hypertree.Label = {};
+
+  /*
+     Hypertree.Label.Native
+
+     Custom extension of <Graph.Label.Native>.
+
+     Extends:
+
+     All <Graph.Label.Native> methods
+
+     See also:
+
+     <Graph.Label.Native>
+
+  */
+  Hypertree.Label.Native = new Class( {
+    Implements: Graph.Label.Native,
+
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+
+    renderLabel: function(canvas, node, controller) {
+      var ctx = canvas.getCtx();
+      var coord = node.pos.getc(true);
+      var s = this.viz.getRadius();
+      ctx.fillText(node.name, coord.x * s, coord.y * s);
+    }
+  });
+
+  /*
+     Hypertree.Label.SVG
+
+    Custom extension of <Graph.Label.SVG>.
+  
+    Extends:
+  
+    All <Graph.Label.SVG> methods
+  
+    See also:
+  
+    <Graph.Label.SVG>
+  
+  */
+  Hypertree.Label.SVG = new Class( {
+    Implements: Graph.Label.SVG,
+
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+
+    /* 
+       placeLabel
+
+       Overrides abstract method placeLabel in <Graph.Plot>.
+
+       Parameters:
+
+       tag - A DOM label element.
+       node - A <Graph.Node>.
+       controller - A configuration/controller object passed to the visualization.
+      
+     */
+    placeLabel: function(tag, node, controller) {
+      var pos = node.pos.getc(true), 
+          canvas = this.viz.canvas,
+          ox = canvas.translateOffsetX,
+          oy = canvas.translateOffsetY,
+          sx = canvas.scaleOffsetX,
+          sy = canvas.scaleOffsetY,
+          radius = canvas.getSize(),
+          r = this.viz.getRadius();
+      var labelPos = {
+        x: Math.round((pos.x * sx) * r + ox + radius.width / 2),
+        y: Math.round((pos.y * sy) * r + oy + radius.height / 2)
+      };
+      tag.setAttribute('x', labelPos.x);
+      tag.setAttribute('y', labelPos.y);
+      controller.onPlaceLabel(tag, node);
+    }
+  });
+
+  /*
+     Hypertree.Label.HTML
+
+     Custom extension of <Graph.Label.HTML>.
+
+     Extends:
+
+     All <Graph.Label.HTML> methods.
+
+     See also:
+
+     <Graph.Label.HTML>
+
+  */
+  Hypertree.Label.HTML = new Class( {
+    Implements: Graph.Label.HTML,
+
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+    /* 
+       placeLabel
+
+       Overrides abstract method placeLabel in <Graph.Plot>.
+
+       Parameters:
+
+       tag - A DOM label element.
+       node - A <Graph.Node>.
+       controller - A configuration/controller object passed to the visualization.
+      
+     */
+    placeLabel: function(tag, node, controller) {
+      var pos = node.pos.getc(true), 
+          canvas = this.viz.canvas,
+          ox = canvas.translateOffsetX,
+          oy = canvas.translateOffsetY,
+          sx = canvas.scaleOffsetX,
+          sy = canvas.scaleOffsetY,
+          radius = canvas.getSize(),
+          r = this.viz.getRadius();
+      var labelPos = {
+        x: Math.round((pos.x * sx) * r + ox + radius.width / 2),
+        y: Math.round((pos.y * sy) * r + oy + radius.height / 2)
+      };
+      var style = tag.style;
+      style.left = labelPos.x + 'px';
+      style.top = labelPos.y + 'px';
+      style.display = this.fitsInCanvas(labelPos, canvas) ? '' : 'none';
+
+      controller.onPlaceLabel(tag, node);
+    }
+  });
+
+  /*
+    Class: Hypertree.Plot.NodeTypes
+
+    This class contains a list of <Graph.Node> built-in types. 
+    Node types implemented are 'none', 'circle', 'triangle', 'rectangle', 'star', 'ellipse' and 'square'.
+
+    You can add your custom node types, customizing your visualization to the extreme.
+
+    Example:
+
+    (start code js)
+      Hypertree.Plot.NodeTypes.implement({
+        'mySpecialType': {
+          'render': function(node, canvas) {
+            //print your custom node to canvas
+          },
+          //optional
+          'contains': function(node, pos) {
+            //return true if pos is inside the node or false otherwise
+          }
+        }
+      });
+    (end code)
+
+  */
+  Hypertree.Plot.NodeTypes = new Class({
+    'none': {
+      'render': $.empty,
+      'contains': $.lambda(false)
+    },
+    'circle': {
+      'render': function(node, canvas) {
+        var nconfig = this.node,
+            dim = node.getData('dim'),
+            p = node.pos.getc();
+        dim = nconfig.transform? dim * (1 - p.squaredNorm()) : dim;
+        p.$scale(node.scale);
+        if (dim > 0.2) {
+          this.nodeHelper.circle.render('fill', p, dim, canvas);
+        }
+      },
+      'contains': function(node, pos) {
+        var dim = node.getData('dim'),
+            npos = node.pos.getc().$scale(node.scale);
+        return this.nodeHelper.circle.contains(npos, pos, dim);
+      }
+    },
+    'ellipse': {
+      'render': function(node, canvas) {
+        var pos = node.pos.getc().$scale(node.scale),
+            width = node.getData('width'),
+            height = node.getData('height');
+        this.nodeHelper.ellipse.render('fill', pos, width, height, canvas);
+      },
+      'contains': function(node, pos) {
+        var width = node.getData('width'),
+            height = node.getData('height'),
+            npos = node.pos.getc().$scale(node.scale);
+        return this.nodeHelper.circle.contains(npos, pos, width, height);
+      }
+    },
+    'square': {
+      'render': function(node, canvas) {
+        var nconfig = this.node,
+            dim = node.getData('dim'),
+            p = node.pos.getc();
+        dim = nconfig.transform? dim * (1 - p.squaredNorm()) : dim;
+        p.$scale(node.scale);
+        if (dim > 0.2) {
+          this.nodeHelper.square.render('fill', p, dim, canvas);
+        }
+      },
+      'contains': function(node, pos) {
+        var dim = node.getData('dim'),
+            npos = node.pos.getc().$scale(node.scale);
+        return this.nodeHelper.square.contains(npos, pos, dim);
+      }
+    },
+    'rectangle': {
+      'render': function(node, canvas) {
+        var nconfig = this.node,
+            width = node.getData('width'),
+            height = node.getData('height'),
+            pos = node.pos.getc();
+        width = nconfig.transform? width * (1 - pos.squaredNorm()) : width;
+        height = nconfig.transform? height * (1 - pos.squaredNorm()) : height;
+        pos.$scale(node.scale);
+        if (width > 0.2 && height > 0.2) {
+          this.nodeHelper.rectangle.render('fill', pos, width, height, canvas);
+        }
+      },
+      'contains': function(node, pos) {
+        var width = node.getData('width'),
+            height = node.getData('height'),
+            npos = node.pos.getc().$scale(node.scale);
+        return this.nodeHelper.rectangle.contains(npos, pos, width, height);
+      }
+    },
+    'triangle': {
+      'render': function(node, canvas) {
+        var nconfig = this.node,
+            dim = node.getData('dim'),
+            p = node.pos.getc();
+        dim = nconfig.transform? dim * (1 - p.squaredNorm()) : dim;
+        p.$scale(node.scale);
+        if (dim > 0.2) {
+          this.nodeHelper.triangle.render('fill', p, dim, canvas);
+        }
+      },
+      'contains': function(node, pos) {
+        var dim = node.getData('dim'),
+            npos = node.pos.getc().$scale(node.scale);
+        return this.nodeHelper.triangle.contains(npos, pos, dim);
+      }
+    },
+    'star': {
+      'render': function(node, canvas) {
+        var nconfig = this.node,
+            dim = node.getData('dim'),
+            p = node.pos.getc();
+        dim = nconfig.transform? dim * (1 - p.squaredNorm()) : dim;
+        p.$scale(node.scale);
+        if (dim > 0.2) {
+          this.nodeHelper.star.render('fill', p, dim, canvas);
+        }
+      },
+      'contains': function(node, pos) {
+        var dim = node.getData('dim'),
+            npos = node.pos.getc().$scale(node.scale);
+        return this.nodeHelper.star.contains(npos, pos, dim);
+      }
+    }
+  });
+
+  /*
+   Class: Hypertree.Plot.EdgeTypes
+
+    This class contains a list of <Graph.Adjacence> built-in types. 
+    Edge types implemented are 'none', 'line', 'arrow' and 'hyperline'.
+  
+    You can add your custom edge types, customizing your visualization to the extreme.
+  
+    Example:
+  
+    (start code js)
+      Hypertree.Plot.EdgeTypes.implement({
+        'mySpecialType': {
+          'render': function(adj, canvas) {
+            //print your custom edge to canvas
+          },
+          //optional
+          'contains': function(adj, pos) {
+            //return true if pos is inside the arc or false otherwise
+          }
+        }
+      });
+    (end code)
+  
+  */
+  Hypertree.Plot.EdgeTypes = new Class({
+    'none': $.empty,
+    'line': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(true),
+          to = adj.nodeTo.pos.getc(true),
+          r = adj.nodeFrom.scale;
+          this.edgeHelper.line.render({x:from.x*r, y:from.y*r}, {x:to.x*r, y:to.y*r}, canvas);
+      },
+      'contains': function(adj, pos) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true),
+            r = adj.nodeFrom.scale;
+            this.edgeHelper.line.contains({x:from.x*r, y:from.y*r}, {x:to.x*r, y:to.y*r}, pos, this.edge.epsilon);
+      }
+    },
+    'arrow': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true),
+            r = adj.nodeFrom.scale,
+            dim = adj.getData('dim'),
+            direction = adj.data.$direction,
+            inv = (direction && direction.length>1 && direction[0] != adj.nodeFrom.id);
+        this.edgeHelper.arrow.render({x:from.x*r, y:from.y*r}, {x:to.x*r, y:to.y*r}, dim, inv, canvas);
+      },
+      'contains': function(adj, pos) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true),
+            r = adj.nodeFrom.scale;
+        this.edgeHelper.arrow.contains({x:from.x*r, y:from.y*r}, {x:to.x*r, y:to.y*r}, pos, this.edge.epsilon);
+      }
+    },
+    'hyperline': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(),
+            to = adj.nodeTo.pos.getc(),
+            dim = this.viz.getRadius();
+        this.edgeHelper.hyperline.render(from, to, dim, canvas);
+      },
+      'contains': $.lambda(false)
+    }
+  });
+
+})($jit.Hypertree);
+
+
+
+
+ })();
\ No newline at end of file
diff --git a/sdncon/ui/static/js/thirdparty/jquery-1.9.1.js b/sdncon/ui/static/js/thirdparty/jquery-1.9.1.js
new file mode 100755
index 0000000..e2c203f
--- /dev/null
+++ b/sdncon/ui/static/js/thirdparty/jquery-1.9.1.js
@@ -0,0 +1,9597 @@
+/*!
+ * jQuery JavaScript Library v1.9.1
+ * http://jquery.com/
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ *
+ * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2013-2-4
+ */
+(function( window, undefined ) {
+
+// Can't do this because several apps including ASP.NET trace
+// the stack via arguments.caller.callee and Firefox dies if
+// you try to trace through "use strict" call chains. (#13335)
+// Support: Firefox 18+
+//"use strict";
+var
+	// The deferred used on DOM ready
+	readyList,
+
+	// A central reference to the root jQuery(document)
+	rootjQuery,
+
+	// Support: IE<9
+	// For `typeof node.method` instead of `node.method !== undefined`
+	core_strundefined = typeof undefined,
+
+	// Use the correct document accordingly with window argument (sandbox)
+	document = window.document,
+	location = window.location,
+
+	// Map over jQuery in case of overwrite
+	_jQuery = window.jQuery,
+
+	// Map over the $ in case of overwrite
+	_$ = window.$,
+
+	// [[Class]] -> type pairs
+	class2type = {},
+
+	// List of deleted data cache ids, so we can reuse them
+	core_deletedIds = [],
+
+	core_version = "1.9.1",
+
+	// Save a reference to some core methods
+	core_concat = core_deletedIds.concat,
+	core_push = core_deletedIds.push,
+	core_slice = core_deletedIds.slice,
+	core_indexOf = core_deletedIds.indexOf,
+	core_toString = class2type.toString,
+	core_hasOwn = class2type.hasOwnProperty,
+	core_trim = core_version.trim,
+
+	// Define a local copy of jQuery
+	jQuery = function( selector, context ) {
+		// The jQuery object is actually just the init constructor 'enhanced'
+		return new jQuery.fn.init( selector, context, rootjQuery );
+	},
+
+	// Used for matching numbers
+	core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
+
+	// Used for splitting on whitespace
+	core_rnotwhite = /\S+/g,
+
+	// Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
+	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+
+	// A simple way to check for HTML strings
+	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+	// Strict HTML recognition (#11290: must start with <)
+	rquickExpr = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,
+
+	// Match a standalone tag
+	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
+
+	// JSON RegExp
+	rvalidchars = /^[\],:{}\s]*$/,
+	rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+	rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,
+	rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,
+
+	// Matches dashed string for camelizing
+	rmsPrefix = /^-ms-/,
+	rdashAlpha = /-([\da-z])/gi,
+
+	// Used by jQuery.camelCase as callback to replace()
+	fcamelCase = function( all, letter ) {
+		return letter.toUpperCase();
+	},
+
+	// The ready event handler
+	completed = function( event ) {
+
+		// readyState === "complete" is good enough for us to call the dom ready in oldIE
+		if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
+			detach();
+			jQuery.ready();
+		}
+	},
+	// Clean-up method for dom ready events
+	detach = function() {
+		if ( document.addEventListener ) {
+			document.removeEventListener( "DOMContentLoaded", completed, false );
+			window.removeEventListener( "load", completed, false );
+
+		} else {
+			document.detachEvent( "onreadystatechange", completed );
+			window.detachEvent( "onload", completed );
+		}
+	};
+
+jQuery.fn = jQuery.prototype = {
+	// The current version of jQuery being used
+	jquery: core_version,
+
+	constructor: jQuery,
+	init: function( selector, context, rootjQuery ) {
+		var match, elem;
+
+		// HANDLE: $(""), $(null), $(undefined), $(false)
+		if ( !selector ) {
+			return this;
+		}
+
+		// Handle HTML strings
+		if ( typeof selector === "string" ) {
+			if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
+				// Assume that strings that start and end with <> are HTML and skip the regex check
+				match = [ null, selector, null ];
+
+			} else {
+				match = rquickExpr.exec( selector );
+			}
+
+			// Match html or make sure no context is specified for #id
+			if ( match && (match[1] || !context) ) {
+
+				// HANDLE: $(html) -> $(array)
+				if ( match[1] ) {
+					context = context instanceof jQuery ? context[0] : context;
+
+					// scripts is true for back-compat
+					jQuery.merge( this, jQuery.parseHTML(
+						match[1],
+						context && context.nodeType ? context.ownerDocument || context : document,
+						true
+					) );
+
+					// HANDLE: $(html, props)
+					if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
+						for ( match in context ) {
+							// Properties of context are called as methods if possible
+							if ( jQuery.isFunction( this[ match ] ) ) {
+								this[ match ]( context[ match ] );
+
+							// ...and otherwise set as attributes
+							} else {
+								this.attr( match, context[ match ] );
+							}
+						}
+					}
+
+					return this;
+
+				// HANDLE: $(#id)
+				} else {
+					elem = document.getElementById( match[2] );
+
+					// Check parentNode to catch when Blackberry 4.6 returns
+					// nodes that are no longer in the document #6963
+					if ( elem && elem.parentNode ) {
+						// Handle the case where IE and Opera return items
+						// by name instead of ID
+						if ( elem.id !== match[2] ) {
+							return rootjQuery.find( selector );
+						}
+
+						// Otherwise, we inject the element directly into the jQuery object
+						this.length = 1;
+						this[0] = elem;
+					}
+
+					this.context = document;
+					this.selector = selector;
+					return this;
+				}
+
+			// HANDLE: $(expr, $(...))
+			} else if ( !context || context.jquery ) {
+				return ( context || rootjQuery ).find( selector );
+
+			// HANDLE: $(expr, context)
+			// (which is just equivalent to: $(context).find(expr)
+			} else {
+				return this.constructor( context ).find( selector );
+			}
+
+		// HANDLE: $(DOMElement)
+		} else if ( selector.nodeType ) {
+			this.context = this[0] = selector;
+			this.length = 1;
+			return this;
+
+		// HANDLE: $(function)
+		// Shortcut for document ready
+		} else if ( jQuery.isFunction( selector ) ) {
+			return rootjQuery.ready( selector );
+		}
+
+		if ( selector.selector !== undefined ) {
+			this.selector = selector.selector;
+			this.context = selector.context;
+		}
+
+		return jQuery.makeArray( selector, this );
+	},
+
+	// Start with an empty selector
+	selector: "",
+
+	// The default length of a jQuery object is 0
+	length: 0,
+
+	// The number of elements contained in the matched element set
+	size: function() {
+		return this.length;
+	},
+
+	toArray: function() {
+		return core_slice.call( this );
+	},
+
+	// Get the Nth element in the matched element set OR
+	// Get the whole matched element set as a clean array
+	get: function( num ) {
+		return num == null ?
+
+			// Return a 'clean' array
+			this.toArray() :
+
+			// Return just the object
+			( num < 0 ? this[ this.length + num ] : this[ num ] );
+	},
+
+	// Take an array of elements and push it onto the stack
+	// (returning the new matched element set)
+	pushStack: function( elems ) {
+
+		// Build a new jQuery matched element set
+		var ret = jQuery.merge( this.constructor(), elems );
+
+		// Add the old object onto the stack (as a reference)
+		ret.prevObject = this;
+		ret.context = this.context;
+
+		// Return the newly-formed element set
+		return ret;
+	},
+
+	// Execute a callback for every element in the matched set.
+	// (You can seed the arguments with an array of args, but this is
+	// only used internally.)
+	each: function( callback, args ) {
+		return jQuery.each( this, callback, args );
+	},
+
+	ready: function( fn ) {
+		// Add the callback
+		jQuery.ready.promise().done( fn );
+
+		return this;
+	},
+
+	slice: function() {
+		return this.pushStack( core_slice.apply( this, arguments ) );
+	},
+
+	first: function() {
+		return this.eq( 0 );
+	},
+
+	last: function() {
+		return this.eq( -1 );
+	},
+
+	eq: function( i ) {
+		var len = this.length,
+			j = +i + ( i < 0 ? len : 0 );
+		return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
+	},
+
+	map: function( callback ) {
+		return this.pushStack( jQuery.map(this, function( elem, i ) {
+			return callback.call( elem, i, elem );
+		}));
+	},
+
+	end: function() {
+		return this.prevObject || this.constructor(null);
+	},
+
+	// For internal use only.
+	// Behaves like an Array's method, not like a jQuery method.
+	push: core_push,
+	sort: [].sort,
+	splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+	var src, copyIsArray, copy, name, options, clone,
+		target = arguments[0] || {},
+		i = 1,
+		length = arguments.length,
+		deep = false;
+
+	// Handle a deep copy situation
+	if ( typeof target === "boolean" ) {
+		deep = target;
+		target = arguments[1] || {};
+		// skip the boolean and the target
+		i = 2;
+	}
+
+	// Handle case when target is a string or something (possible in deep copy)
+	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+		target = {};
+	}
+
+	// extend jQuery itself if only one argument is passed
+	if ( length === i ) {
+		target = this;
+		--i;
+	}
+
+	for ( ; i < length; i++ ) {
+		// Only deal with non-null/undefined values
+		if ( (options = arguments[ i ]) != null ) {
+			// Extend the base object
+			for ( name in options ) {
+				src = target[ name ];
+				copy = options[ name ];
+
+				// Prevent never-ending loop
+				if ( target === copy ) {
+					continue;
+				}
+
+				// Recurse if we're merging plain objects or arrays
+				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+					if ( copyIsArray ) {
+						copyIsArray = false;
+						clone = src && jQuery.isArray(src) ? src : [];
+
+					} else {
+						clone = src && jQuery.isPlainObject(src) ? src : {};
+					}
+
+					// Never move original objects, clone them
+					target[ name ] = jQuery.extend( deep, clone, copy );
+
+				// Don't bring in undefined values
+				} else if ( copy !== undefined ) {
+					target[ name ] = copy;
+				}
+			}
+		}
+	}
+
+	// Return the modified object
+	return target;
+};
+
+jQuery.extend({
+	noConflict: function( deep ) {
+		if ( window.$ === jQuery ) {
+			window.$ = _$;
+		}
+
+		if ( deep && window.jQuery === jQuery ) {
+			window.jQuery = _jQuery;
+		}
+
+		return jQuery;
+	},
+
+	// Is the DOM ready to be used? Set to true once it occurs.
+	isReady: false,
+
+	// A counter to track how many items to wait for before
+	// the ready event fires. See #6781
+	readyWait: 1,
+
+	// Hold (or release) the ready event
+	holdReady: function( hold ) {
+		if ( hold ) {
+			jQuery.readyWait++;
+		} else {
+			jQuery.ready( true );
+		}
+	},
+
+	// Handle when the DOM is ready
+	ready: function( wait ) {
+
+		// Abort if there are pending holds or we're already ready
+		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+			return;
+		}
+
+		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+		if ( !document.body ) {
+			return setTimeout( jQuery.ready );
+		}
+
+		// Remember that the DOM is ready
+		jQuery.isReady = true;
+
+		// If a normal DOM Ready event fired, decrement, and wait if need be
+		if ( wait !== true && --jQuery.readyWait > 0 ) {
+			return;
+		}
+
+		// If there are functions bound, to execute
+		readyList.resolveWith( document, [ jQuery ] );
+
+		// Trigger any bound ready events
+		if ( jQuery.fn.trigger ) {
+			jQuery( document ).trigger("ready").off("ready");
+		}
+	},
+
+	// See test/unit/core.js for details concerning isFunction.
+	// Since version 1.3, DOM methods and functions like alert
+	// aren't supported. They return false on IE (#2968).
+	isFunction: function( obj ) {
+		return jQuery.type(obj) === "function";
+	},
+
+	isArray: Array.isArray || function( obj ) {
+		return jQuery.type(obj) === "array";
+	},
+
+	isWindow: function( obj ) {
+		return obj != null && obj == obj.window;
+	},
+
+	isNumeric: function( obj ) {
+		return !isNaN( parseFloat(obj) ) && isFinite( obj );
+	},
+
+	type: function( obj ) {
+		if ( obj == null ) {
+			return String( obj );
+		}
+		return typeof obj === "object" || typeof obj === "function" ?
+			class2type[ core_toString.call(obj) ] || "object" :
+			typeof obj;
+	},
+
+	isPlainObject: function( obj ) {
+		// Must be an Object.
+		// Because of IE, we also have to check the presence of the constructor property.
+		// Make sure that DOM nodes and window objects don't pass through, as well
+		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+			return false;
+		}
+
+		try {
+			// Not own constructor property must be Object
+			if ( obj.constructor &&
+				!core_hasOwn.call(obj, "constructor") &&
+				!core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+				return false;
+			}
+		} catch ( e ) {
+			// IE8,9 Will throw exceptions on certain host objects #9897
+			return false;
+		}
+
+		// Own properties are enumerated firstly, so to speed up,
+		// if last one is own, then all properties are own.
+
+		var key;
+		for ( key in obj ) {}
+
+		return key === undefined || core_hasOwn.call( obj, key );
+	},
+
+	isEmptyObject: function( obj ) {
+		var name;
+		for ( name in obj ) {
+			return false;
+		}
+		return true;
+	},
+
+	error: function( msg ) {
+		throw new Error( msg );
+	},
+
+	// data: string of html
+	// context (optional): If specified, the fragment will be created in this context, defaults to document
+	// keepScripts (optional): If true, will include scripts passed in the html string
+	parseHTML: function( data, context, keepScripts ) {
+		if ( !data || typeof data !== "string" ) {
+			return null;
+		}
+		if ( typeof context === "boolean" ) {
+			keepScripts = context;
+			context = false;
+		}
+		context = context || document;
+
+		var parsed = rsingleTag.exec( data ),
+			scripts = !keepScripts && [];
+
+		// Single tag
+		if ( parsed ) {
+			return [ context.createElement( parsed[1] ) ];
+		}
+
+		parsed = jQuery.buildFragment( [ data ], context, scripts );
+		if ( scripts ) {
+			jQuery( scripts ).remove();
+		}
+		return jQuery.merge( [], parsed.childNodes );
+	},
+
+	parseJSON: function( data ) {
+		// Attempt to parse using the native JSON parser first
+		if ( window.JSON && window.JSON.parse ) {
+			return window.JSON.parse( data );
+		}
+
+		if ( data === null ) {
+			return data;
+		}
+
+		if ( typeof data === "string" ) {
+
+			// Make sure leading/trailing whitespace is removed (IE can't handle it)
+			data = jQuery.trim( data );
+
+			if ( data ) {
+				// Make sure the incoming data is actual JSON
+				// Logic borrowed from http://json.org/json2.js
+				if ( rvalidchars.test( data.replace( rvalidescape, "@" )
+					.replace( rvalidtokens, "]" )
+					.replace( rvalidbraces, "")) ) {
+
+					return ( new Function( "return " + data ) )();
+				}
+			}
+		}
+
+		jQuery.error( "Invalid JSON: " + data );
+	},
+
+	// Cross-browser xml parsing
+	parseXML: function( data ) {
+		var xml, tmp;
+		if ( !data || typeof data !== "string" ) {
+			return null;
+		}
+		try {
+			if ( window.DOMParser ) { // Standard
+				tmp = new DOMParser();
+				xml = tmp.parseFromString( data , "text/xml" );
+			} else { // IE
+				xml = new ActiveXObject( "Microsoft.XMLDOM" );
+				xml.async = "false";
+				xml.loadXML( data );
+			}
+		} catch( e ) {
+			xml = undefined;
+		}
+		if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
+			jQuery.error( "Invalid XML: " + data );
+		}
+		return xml;
+	},
+
+	noop: function() {},
+
+	// Evaluates a script in a global context
+	// Workarounds based on findings by Jim Driscoll
+	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+	globalEval: function( data ) {
+		if ( data && jQuery.trim( data ) ) {
+			// We use execScript on Internet Explorer
+			// We use an anonymous function so that context is window
+			// rather than jQuery in Firefox
+			( window.execScript || function( data ) {
+				window[ "eval" ].call( window, data );
+			} )( data );
+		}
+	},
+
+	// Convert dashed to camelCase; used by the css and data modules
+	// Microsoft forgot to hump their vendor prefix (#9572)
+	camelCase: function( string ) {
+		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+	},
+
+	nodeName: function( elem, name ) {
+		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+	},
+
+	// args is for internal usage only
+	each: function( obj, callback, args ) {
+		var value,
+			i = 0,
+			length = obj.length,
+			isArray = isArraylike( obj );
+
+		if ( args ) {
+			if ( isArray ) {
+				for ( ; i < length; i++ ) {
+					value = callback.apply( obj[ i ], args );
+
+					if ( value === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( i in obj ) {
+					value = callback.apply( obj[ i ], args );
+
+					if ( value === false ) {
+						break;
+					}
+				}
+			}
+
+		// A special, fast, case for the most common use of each
+		} else {
+			if ( isArray ) {
+				for ( ; i < length; i++ ) {
+					value = callback.call( obj[ i ], i, obj[ i ] );
+
+					if ( value === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( i in obj ) {
+					value = callback.call( obj[ i ], i, obj[ i ] );
+
+					if ( value === false ) {
+						break;
+					}
+				}
+			}
+		}
+
+		return obj;
+	},
+
+	// Use native String.trim function wherever possible
+	trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
+		function( text ) {
+			return text == null ?
+				"" :
+				core_trim.call( text );
+		} :
+
+		// Otherwise use our own trimming functionality
+		function( text ) {
+			return text == null ?
+				"" :
+				( text + "" ).replace( rtrim, "" );
+		},
+
+	// results is for internal usage only
+	makeArray: function( arr, results ) {
+		var ret = results || [];
+
+		if ( arr != null ) {
+			if ( isArraylike( Object(arr) ) ) {
+				jQuery.merge( ret,
+					typeof arr === "string" ?
+					[ arr ] : arr
+				);
+			} else {
+				core_push.call( ret, arr );
+			}
+		}
+
+		return ret;
+	},
+
+	inArray: function( elem, arr, i ) {
+		var len;
+
+		if ( arr ) {
+			if ( core_indexOf ) {
+				return core_indexOf.call( arr, elem, i );
+			}
+
+			len = arr.length;
+			i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
+
+			for ( ; i < len; i++ ) {
+				// Skip accessing in sparse arrays
+				if ( i in arr && arr[ i ] === elem ) {
+					return i;
+				}
+			}
+		}
+
+		return -1;
+	},
+
+	merge: function( first, second ) {
+		var l = second.length,
+			i = first.length,
+			j = 0;
+
+		if ( typeof l === "number" ) {
+			for ( ; j < l; j++ ) {
+				first[ i++ ] = second[ j ];
+			}
+		} else {
+			while ( second[j] !== undefined ) {
+				first[ i++ ] = second[ j++ ];
+			}
+		}
+
+		first.length = i;
+
+		return first;
+	},
+
+	grep: function( elems, callback, inv ) {
+		var retVal,
+			ret = [],
+			i = 0,
+			length = elems.length;
+		inv = !!inv;
+
+		// Go through the array, only saving the items
+		// that pass the validator function
+		for ( ; i < length; i++ ) {
+			retVal = !!callback( elems[ i ], i );
+			if ( inv !== retVal ) {
+				ret.push( elems[ i ] );
+			}
+		}
+
+		return ret;
+	},
+
+	// arg is for internal usage only
+	map: function( elems, callback, arg ) {
+		var value,
+			i = 0,
+			length = elems.length,
+			isArray = isArraylike( elems ),
+			ret = [];
+
+		// Go through the array, translating each of the items to their
+		if ( isArray ) {
+			for ( ; i < length; i++ ) {
+				value = callback( elems[ i ], i, arg );
+
+				if ( value != null ) {
+					ret[ ret.length ] = value;
+				}
+			}
+
+		// Go through every key on the object,
+		} else {
+			for ( i in elems ) {
+				value = callback( elems[ i ], i, arg );
+
+				if ( value != null ) {
+					ret[ ret.length ] = value;
+				}
+			}
+		}
+
+		// Flatten any nested arrays
+		return core_concat.apply( [], ret );
+	},
+
+	// A global GUID counter for objects
+	guid: 1,
+
+	// Bind a function to a context, optionally partially applying any
+	// arguments.
+	proxy: function( fn, context ) {
+		var args, proxy, tmp;
+
+		if ( typeof context === "string" ) {
+			tmp = fn[ context ];
+			context = fn;
+			fn = tmp;
+		}
+
+		// Quick check to determine if target is callable, in the spec
+		// this throws a TypeError, but we will just return undefined.
+		if ( !jQuery.isFunction( fn ) ) {
+			return undefined;
+		}
+
+		// Simulated bind
+		args = core_slice.call( arguments, 2 );
+		proxy = function() {
+			return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
+		};
+
+		// Set the guid of unique handler to the same of original handler, so it can be removed
+		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
+
+		return proxy;
+	},
+
+	// Multifunctional method to get and set values of a collection
+	// The value/s can optionally be executed if it's a function
+	access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
+		var i = 0,
+			length = elems.length,
+			bulk = key == null;
+
+		// Sets many values
+		if ( jQuery.type( key ) === "object" ) {
+			chainable = true;
+			for ( i in key ) {
+				jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
+			}
+
+		// Sets one value
+		} else if ( value !== undefined ) {
+			chainable = true;
+
+			if ( !jQuery.isFunction( value ) ) {
+				raw = true;
+			}
+
+			if ( bulk ) {
+				// Bulk operations run against the entire set
+				if ( raw ) {
+					fn.call( elems, value );
+					fn = null;
+
+				// ...except when executing function values
+				} else {
+					bulk = fn;
+					fn = function( elem, key, value ) {
+						return bulk.call( jQuery( elem ), value );
+					};
+				}
+			}
+
+			if ( fn ) {
+				for ( ; i < length; i++ ) {
+					fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
+				}
+			}
+		}
+
+		return chainable ?
+			elems :
+
+			// Gets
+			bulk ?
+				fn.call( elems ) :
+				length ? fn( elems[0], key ) : emptyGet;
+	},
+
+	now: function() {
+		return ( new Date() ).getTime();
+	}
+});
+
+jQuery.ready.promise = function( obj ) {
+	if ( !readyList ) {
+
+		readyList = jQuery.Deferred();
+
+		// Catch cases where $(document).ready() is called after the browser event has already occurred.
+		// we once tried to use readyState "interactive" here, but it caused issues like the one
+		// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
+		if ( document.readyState === "complete" ) {
+			// Handle it asynchronously to allow scripts the opportunity to delay ready
+			setTimeout( jQuery.ready );
+
+		// Standards-based browsers support DOMContentLoaded
+		} else if ( document.addEventListener ) {
+			// Use the handy event callback
+			document.addEventListener( "DOMContentLoaded", completed, false );
+
+			// A fallback to window.onload, that will always work
+			window.addEventListener( "load", completed, false );
+
+		// If IE event model is used
+		} else {
+			// Ensure firing before onload, maybe late but safe also for iframes
+			document.attachEvent( "onreadystatechange", completed );
+
+			// A fallback to window.onload, that will always work
+			window.attachEvent( "onload", completed );
+
+			// If IE and not a frame
+			// continually check to see if the document is ready
+			var top = false;
+
+			try {
+				top = window.frameElement == null && document.documentElement;
+			} catch(e) {}
+
+			if ( top && top.doScroll ) {
+				(function doScrollCheck() {
+					if ( !jQuery.isReady ) {
+
+						try {
+							// Use the trick by Diego Perini
+							// http://javascript.nwbox.com/IEContentLoaded/
+							top.doScroll("left");
+						} catch(e) {
+							return setTimeout( doScrollCheck, 50 );
+						}
+
+						// detach all dom ready events
+						detach();
+
+						// and execute any waiting functions
+						jQuery.ready();
+					}
+				})();
+			}
+		}
+	}
+	return readyList.promise( obj );
+};
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
+	class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+function isArraylike( obj ) {
+	var length = obj.length,
+		type = jQuery.type( obj );
+
+	if ( jQuery.isWindow( obj ) ) {
+		return false;
+	}
+
+	if ( obj.nodeType === 1 && length ) {
+		return true;
+	}
+
+	return type === "array" || type !== "function" &&
+		( length === 0 ||
+		typeof length === "number" && length > 0 && ( length - 1 ) in obj );
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+// String to Object options format cache
+var optionsCache = {};
+
+// Convert String-formatted options into Object-formatted ones and store in cache
+function createOptions( options ) {
+	var object = optionsCache[ options ] = {};
+	jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {
+		object[ flag ] = true;
+	});
+	return object;
+}
+
+/*
+ * Create a callback list using the following parameters:
+ *
+ *	options: an optional list of space-separated options that will change how
+ *			the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ *	once:			will ensure the callback list can only be fired once (like a Deferred)
+ *
+ *	memory:			will keep track of previous values and will call any callback added
+ *					after the list has been fired right away with the latest "memorized"
+ *					values (like a Deferred)
+ *
+ *	unique:			will ensure a callback can only be added once (no duplicate in the list)
+ *
+ *	stopOnFalse:	interrupt callings when a callback returns false
+ *
+ */
+jQuery.Callbacks = function( options ) {
+
+	// Convert options from String-formatted to Object-formatted if needed
+	// (we check in cache first)
+	options = typeof options === "string" ?
+		( optionsCache[ options ] || createOptions( options ) ) :
+		jQuery.extend( {}, options );
+
+	var // Flag to know if list is currently firing
+		firing,
+		// Last fire value (for non-forgettable lists)
+		memory,
+		// Flag to know if list was already fired
+		fired,
+		// End of the loop when firing
+		firingLength,
+		// Index of currently firing callback (modified by remove if needed)
+		firingIndex,
+		// First callback to fire (used internally by add and fireWith)
+		firingStart,
+		// Actual callback list
+		list = [],
+		// Stack of fire calls for repeatable lists
+		stack = !options.once && [],
+		// Fire callbacks
+		fire = function( data ) {
+			memory = options.memory && data;
+			fired = true;
+			firingIndex = firingStart || 0;
+			firingStart = 0;
+			firingLength = list.length;
+			firing = true;
+			for ( ; list && firingIndex < firingLength; firingIndex++ ) {
+				if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
+					memory = false; // To prevent further calls using add
+					break;
+				}
+			}
+			firing = false;
+			if ( list ) {
+				if ( stack ) {
+					if ( stack.length ) {
+						fire( stack.shift() );
+					}
+				} else if ( memory ) {
+					list = [];
+				} else {
+					self.disable();
+				}
+			}
+		},
+		// Actual Callbacks object
+		self = {
+			// Add a callback or a collection of callbacks to the list
+			add: function() {
+				if ( list ) {
+					// First, we save the current length
+					var start = list.length;
+					(function add( args ) {
+						jQuery.each( args, function( _, arg ) {
+							var type = jQuery.type( arg );
+							if ( type === "function" ) {
+								if ( !options.unique || !self.has( arg ) ) {
+									list.push( arg );
+								}
+							} else if ( arg && arg.length && type !== "string" ) {
+								// Inspect recursively
+								add( arg );
+							}
+						});
+					})( arguments );
+					// Do we need to add the callbacks to the
+					// current firing batch?
+					if ( firing ) {
+						firingLength = list.length;
+					// With memory, if we're not firing then
+					// we should call right away
+					} else if ( memory ) {
+						firingStart = start;
+						fire( memory );
+					}
+				}
+				return this;
+			},
+			// Remove a callback from the list
+			remove: function() {
+				if ( list ) {
+					jQuery.each( arguments, function( _, arg ) {
+						var index;
+						while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+							list.splice( index, 1 );
+							// Handle firing indexes
+							if ( firing ) {
+								if ( index <= firingLength ) {
+									firingLength--;
+								}
+								if ( index <= firingIndex ) {
+									firingIndex--;
+								}
+							}
+						}
+					});
+				}
+				return this;
+			},
+			// Check if a given callback is in the list.
+			// If no argument is given, return whether or not list has callbacks attached.
+			has: function( fn ) {
+				return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
+			},
+			// Remove all callbacks from the list
+			empty: function() {
+				list = [];
+				return this;
+			},
+			// Have the list do nothing anymore
+			disable: function() {
+				list = stack = memory = undefined;
+				return this;
+			},
+			// Is it disabled?
+			disabled: function() {
+				return !list;
+			},
+			// Lock the list in its current state
+			lock: function() {
+				stack = undefined;
+				if ( !memory ) {
+					self.disable();
+				}
+				return this;
+			},
+			// Is it locked?
+			locked: function() {
+				return !stack;
+			},
+			// Call all callbacks with the given context and arguments
+			fireWith: function( context, args ) {
+				args = args || [];
+				args = [ context, args.slice ? args.slice() : args ];
+				if ( list && ( !fired || stack ) ) {
+					if ( firing ) {
+						stack.push( args );
+					} else {
+						fire( args );
+					}
+				}
+				return this;
+			},
+			// Call all the callbacks with the given arguments
+			fire: function() {
+				self.fireWith( this, arguments );
+				return this;
+			},
+			// To know if the callbacks have already been called at least once
+			fired: function() {
+				return !!fired;
+			}
+		};
+
+	return self;
+};
+jQuery.extend({
+
+	Deferred: function( func ) {
+		var tuples = [
+				// action, add listener, listener list, final state
+				[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
+				[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
+				[ "notify", "progress", jQuery.Callbacks("memory") ]
+			],
+			state = "pending",
+			promise = {
+				state: function() {
+					return state;
+				},
+				always: function() {
+					deferred.done( arguments ).fail( arguments );
+					return this;
+				},
+				then: function( /* fnDone, fnFail, fnProgress */ ) {
+					var fns = arguments;
+					return jQuery.Deferred(function( newDefer ) {
+						jQuery.each( tuples, function( i, tuple ) {
+							var action = tuple[ 0 ],
+								fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
+							// deferred[ done | fail | progress ] for forwarding actions to newDefer
+							deferred[ tuple[1] ](function() {
+								var returned = fn && fn.apply( this, arguments );
+								if ( returned && jQuery.isFunction( returned.promise ) ) {
+									returned.promise()
+										.done( newDefer.resolve )
+										.fail( newDefer.reject )
+										.progress( newDefer.notify );
+								} else {
+									newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
+								}
+							});
+						});
+						fns = null;
+					}).promise();
+				},
+				// Get a promise for this deferred
+				// If obj is provided, the promise aspect is added to the object
+				promise: function( obj ) {
+					return obj != null ? jQuery.extend( obj, promise ) : promise;
+				}
+			},
+			deferred = {};
+
+		// Keep pipe for back-compat
+		promise.pipe = promise.then;
+
+		// Add list-specific methods
+		jQuery.each( tuples, function( i, tuple ) {
+			var list = tuple[ 2 ],
+				stateString = tuple[ 3 ];
+
+			// promise[ done | fail | progress ] = list.add
+			promise[ tuple[1] ] = list.add;
+
+			// Handle state
+			if ( stateString ) {
+				list.add(function() {
+					// state = [ resolved | rejected ]
+					state = stateString;
+
+				// [ reject_list | resolve_list ].disable; progress_list.lock
+				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
+			}
+
+			// deferred[ resolve | reject | notify ]
+			deferred[ tuple[0] ] = function() {
+				deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
+				return this;
+			};
+			deferred[ tuple[0] + "With" ] = list.fireWith;
+		});
+
+		// Make the deferred a promise
+		promise.promise( deferred );
+
+		// Call given func if any
+		if ( func ) {
+			func.call( deferred, deferred );
+		}
+
+		// All done!
+		return deferred;
+	},
+
+	// Deferred helper
+	when: function( subordinate /* , ..., subordinateN */ ) {
+		var i = 0,
+			resolveValues = core_slice.call( arguments ),
+			length = resolveValues.length,
+
+			// the count of uncompleted subordinates
+			remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
+
+			// the master Deferred. If resolveValues consist of only a single Deferred, just use that.
+			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
+
+			// Update function for both resolve and progress values
+			updateFunc = function( i, contexts, values ) {
+				return function( value ) {
+					contexts[ i ] = this;
+					values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
+					if( values === progressValues ) {
+						deferred.notifyWith( contexts, values );
+					} else if ( !( --remaining ) ) {
+						deferred.resolveWith( contexts, values );
+					}
+				};
+			},
+
+			progressValues, progressContexts, resolveContexts;
+
+		// add listeners to Deferred subordinates; treat others as resolved
+		if ( length > 1 ) {
+			progressValues = new Array( length );
+			progressContexts = new Array( length );
+			resolveContexts = new Array( length );
+			for ( ; i < length; i++ ) {
+				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
+					resolveValues[ i ].promise()
+						.done( updateFunc( i, resolveContexts, resolveValues ) )
+						.fail( deferred.reject )
+						.progress( updateFunc( i, progressContexts, progressValues ) );
+				} else {
+					--remaining;
+				}
+			}
+		}
+
+		// if we're not waiting on anything, resolve the master
+		if ( !remaining ) {
+			deferred.resolveWith( resolveContexts, resolveValues );
+		}
+
+		return deferred.promise();
+	}
+});
+jQuery.support = (function() {
+
+	var support, all, a,
+		input, select, fragment,
+		opt, eventName, isSupported, i,
+		div = document.createElement("div");
+
+	// Setup
+	div.setAttribute( "className", "t" );
+	div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
+
+	// Support tests won't run in some limited or non-browser environments
+	all = div.getElementsByTagName("*");
+	a = div.getElementsByTagName("a")[ 0 ];
+	if ( !all || !a || !all.length ) {
+		return {};
+	}
+
+	// First batch of tests
+	select = document.createElement("select");
+	opt = select.appendChild( document.createElement("option") );
+	input = div.getElementsByTagName("input")[ 0 ];
+
+	a.style.cssText = "top:1px;float:left;opacity:.5";
+	support = {
+		// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
+		getSetAttribute: div.className !== "t",
+
+		// IE strips leading whitespace when .innerHTML is used
+		leadingWhitespace: div.firstChild.nodeType === 3,
+
+		// Make sure that tbody elements aren't automatically inserted
+		// IE will insert them into empty tables
+		tbody: !div.getElementsByTagName("tbody").length,
+
+		// Make sure that link elements get serialized correctly by innerHTML
+		// This requires a wrapper element in IE
+		htmlSerialize: !!div.getElementsByTagName("link").length,
+
+		// Get the style information from getAttribute
+		// (IE uses .cssText instead)
+		style: /top/.test( a.getAttribute("style") ),
+
+		// Make sure that URLs aren't manipulated
+		// (IE normalizes it by default)
+		hrefNormalized: a.getAttribute("href") === "/a",
+
+		// Make sure that element opacity exists
+		// (IE uses filter instead)
+		// Use a regex to work around a WebKit issue. See #5145
+		opacity: /^0.5/.test( a.style.opacity ),
+
+		// Verify style float existence
+		// (IE uses styleFloat instead of cssFloat)
+		cssFloat: !!a.style.cssFloat,
+
+		// Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
+		checkOn: !!input.value,
+
+		// Make sure that a selected-by-default option has a working selected property.
+		// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+		optSelected: opt.selected,
+
+		// Tests for enctype support on a form (#6743)
+		enctype: !!document.createElement("form").enctype,
+
+		// Makes sure cloning an html5 element does not cause problems
+		// Where outerHTML is undefined, this still works
+		html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",
+
+		// jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode
+		boxModel: document.compatMode === "CSS1Compat",
+
+		// Will be defined later
+		deleteExpando: true,
+		noCloneEvent: true,
+		inlineBlockNeedsLayout: false,
+		shrinkWrapBlocks: false,
+		reliableMarginRight: true,
+		boxSizingReliable: true,
+		pixelPosition: false
+	};
+
+	// Make sure checked status is properly cloned
+	input.checked = true;
+	support.noCloneChecked = input.cloneNode( true ).checked;
+
+	// Make sure that the options inside disabled selects aren't marked as disabled
+	// (WebKit marks them as disabled)
+	select.disabled = true;
+	support.optDisabled = !opt.disabled;
+
+	// Support: IE<9
+	try {
+		delete div.test;
+	} catch( e ) {
+		support.deleteExpando = false;
+	}
+
+	// Check if we can trust getAttribute("value")
+	input = document.createElement("input");
+	input.setAttribute( "value", "" );
+	support.input = input.getAttribute( "value" ) === "";
+
+	// Check if an input maintains its value after becoming a radio
+	input.value = "t";
+	input.setAttribute( "type", "radio" );
+	support.radioValue = input.value === "t";
+
+	// #11217 - WebKit loses check when the name is after the checked attribute
+	input.setAttribute( "checked", "t" );
+	input.setAttribute( "name", "t" );
+
+	fragment = document.createDocumentFragment();
+	fragment.appendChild( input );
+
+	// Check if a disconnected checkbox will retain its checked
+	// value of true after appended to the DOM (IE6/7)
+	support.appendChecked = input.checked;
+
+	// WebKit doesn't clone checked state correctly in fragments
+	support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+	// Support: IE<9
+	// Opera does not clone events (and typeof div.attachEvent === undefined).
+	// IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
+	if ( div.attachEvent ) {
+		div.attachEvent( "onclick", function() {
+			support.noCloneEvent = false;
+		});
+
+		div.cloneNode( true ).click();
+	}
+
+	// Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event)
+	// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP), test/csp.php
+	for ( i in { submit: true, change: true, focusin: true }) {
+		div.setAttribute( eventName = "on" + i, "t" );
+
+		support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false;
+	}
+
+	div.style.backgroundClip = "content-box";
+	div.cloneNode( true ).style.backgroundClip = "";
+	support.clearCloneStyle = div.style.backgroundClip === "content-box";
+
+	// Run tests that need a body at doc ready
+	jQuery(function() {
+		var container, marginDiv, tds,
+			divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",
+			body = document.getElementsByTagName("body")[0];
+
+		if ( !body ) {
+			// Return for frameset docs that don't have a body
+			return;
+		}
+
+		container = document.createElement("div");
+		container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";
+
+		body.appendChild( container ).appendChild( div );
+
+		// Support: IE8
+		// Check if table cells still have offsetWidth/Height when they are set
+		// to display:none and there are still other visible table cells in a
+		// table row; if so, offsetWidth/Height are not reliable for use when
+		// determining if an element has been hidden directly using
+		// display:none (it is still safe to use offsets if a parent element is
+		// hidden; don safety goggles and see bug #4512 for more information).
+		div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
+		tds = div.getElementsByTagName("td");
+		tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none";
+		isSupported = ( tds[ 0 ].offsetHeight === 0 );
+
+		tds[ 0 ].style.display = "";
+		tds[ 1 ].style.display = "none";
+
+		// Support: IE8
+		// Check if empty table cells still have offsetWidth/Height
+		support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
+
+		// Check box-sizing and margin behavior
+		div.innerHTML = "";
+		div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";
+		support.boxSizing = ( div.offsetWidth === 4 );
+		support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );
+
+		// Use window.getComputedStyle because jsdom on node.js will break without it.
+		if ( window.getComputedStyle ) {
+			support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
+			support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
+
+			// Check if div with explicit width and no margin-right incorrectly
+			// gets computed margin-right based on width of container. (#3333)
+			// Fails in WebKit before Feb 2011 nightlies
+			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+			marginDiv = div.appendChild( document.createElement("div") );
+			marginDiv.style.cssText = div.style.cssText = divReset;
+			marginDiv.style.marginRight = marginDiv.style.width = "0";
+			div.style.width = "1px";
+
+			support.reliableMarginRight =
+				!parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
+		}
+
+		if ( typeof div.style.zoom !== core_strundefined ) {
+			// Support: IE<8
+			// Check if natively block-level elements act like inline-block
+			// elements when setting their display to 'inline' and giving
+			// them layout
+			div.innerHTML = "";
+			div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1";
+			support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
+
+			// Support: IE6
+			// Check if elements with layout shrink-wrap their children
+			div.style.display = "block";
+			div.innerHTML = "<div></div>";
+			div.firstChild.style.width = "5px";
+			support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
+
+			if ( support.inlineBlockNeedsLayout ) {
+				// Prevent IE 6 from affecting layout for positioned elements #11048
+				// Prevent IE from shrinking the body in IE 7 mode #12869
+				// Support: IE<8
+				body.style.zoom = 1;
+			}
+		}
+
+		body.removeChild( container );
+
+		// Null elements to avoid leaks in IE
+		container = div = tds = marginDiv = null;
+	});
+
+	// Null elements to avoid leaks in IE
+	all = select = fragment = opt = a = input = null;
+
+	return support;
+})();
+
+var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
+	rmultiDash = /([A-Z])/g;
+
+function internalData( elem, name, data, pvt /* Internal Use Only */ ){
+	if ( !jQuery.acceptData( elem ) ) {
+		return;
+	}
+
+	var thisCache, ret,
+		internalKey = jQuery.expando,
+		getByName = typeof name === "string",
+
+		// We have to handle DOM nodes and JS objects differently because IE6-7
+		// can't GC object references properly across the DOM-JS boundary
+		isNode = elem.nodeType,
+
+		// Only DOM nodes need the global jQuery cache; JS object data is
+		// attached directly to the object so GC can occur automatically
+		cache = isNode ? jQuery.cache : elem,
+
+		// Only defining an ID for JS objects if its cache already exists allows
+		// the code to shortcut on the same path as a DOM node with no cache
+		id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
+
+	// Avoid doing any more work than we need to when trying to get data on an
+	// object that has no data at all
+	if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) {
+		return;
+	}
+
+	if ( !id ) {
+		// Only DOM nodes need a new unique ID for each element since their data
+		// ends up in the global cache
+		if ( isNode ) {
+			elem[ internalKey ] = id = core_deletedIds.pop() || jQuery.guid++;
+		} else {
+			id = internalKey;
+		}
+	}
+
+	if ( !cache[ id ] ) {
+		cache[ id ] = {};
+
+		// Avoids exposing jQuery metadata on plain JS objects when the object
+		// is serialized using JSON.stringify
+		if ( !isNode ) {
+			cache[ id ].toJSON = jQuery.noop;
+		}
+	}
+
+	// An object can be passed to jQuery.data instead of a key/value pair; this gets
+	// shallow copied over onto the existing cache
+	if ( typeof name === "object" || typeof name === "function" ) {
+		if ( pvt ) {
+			cache[ id ] = jQuery.extend( cache[ id ], name );
+		} else {
+			cache[ id ].data = jQuery.extend( cache[ id ].data, name );
+		}
+	}
+
+	thisCache = cache[ id ];
+
+	// jQuery data() is stored in a separate object inside the object's internal data
+	// cache in order to avoid key collisions between internal data and user-defined
+	// data.
+	if ( !pvt ) {
+		if ( !thisCache.data ) {
+			thisCache.data = {};
+		}
+
+		thisCache = thisCache.data;
+	}
+
+	if ( data !== undefined ) {
+		thisCache[ jQuery.camelCase( name ) ] = data;
+	}
+
+	// Check for both converted-to-camel and non-converted data property names
+	// If a data property was specified
+	if ( getByName ) {
+
+		// First Try to find as-is property data
+		ret = thisCache[ name ];
+
+		// Test for null|undefined property data
+		if ( ret == null ) {
+
+			// Try to find the camelCased property
+			ret = thisCache[ jQuery.camelCase( name ) ];
+		}
+	} else {
+		ret = thisCache;
+	}
+
+	return ret;
+}
+
+function internalRemoveData( elem, name, pvt ) {
+	if ( !jQuery.acceptData( elem ) ) {
+		return;
+	}
+
+	var i, l, thisCache,
+		isNode = elem.nodeType,
+
+		// See jQuery.data for more information
+		cache = isNode ? jQuery.cache : elem,
+		id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
+
+	// If there is already no cache entry for this object, there is no
+	// purpose in continuing
+	if ( !cache[ id ] ) {
+		return;
+	}
+
+	if ( name ) {
+
+		thisCache = pvt ? cache[ id ] : cache[ id ].data;
+
+		if ( thisCache ) {
+
+			// Support array or space separated string names for data keys
+			if ( !jQuery.isArray( name ) ) {
+
+				// try the string as a key before any manipulation
+				if ( name in thisCache ) {
+					name = [ name ];
+				} else {
+
+					// split the camel cased version by spaces unless a key with the spaces exists
+					name = jQuery.camelCase( name );
+					if ( name in thisCache ) {
+						name = [ name ];
+					} else {
+						name = name.split(" ");
+					}
+				}
+			} else {
+				// If "name" is an array of keys...
+				// When data is initially created, via ("key", "val") signature,
+				// keys will be converted to camelCase.
+				// Since there is no way to tell _how_ a key was added, remove
+				// both plain key and camelCase key. #12786
+				// This will only penalize the array argument path.
+				name = name.concat( jQuery.map( name, jQuery.camelCase ) );
+			}
+
+			for ( i = 0, l = name.length; i < l; i++ ) {
+				delete thisCache[ name[i] ];
+			}
+
+			// If there is no data left in the cache, we want to continue
+			// and let the cache object itself get destroyed
+			if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
+				return;
+			}
+		}
+	}
+
+	// See jQuery.data for more information
+	if ( !pvt ) {
+		delete cache[ id ].data;
+
+		// Don't destroy the parent cache unless the internal data object
+		// had been the only thing left in it
+		if ( !isEmptyDataObject( cache[ id ] ) ) {
+			return;
+		}
+	}
+
+	// Destroy the cache
+	if ( isNode ) {
+		jQuery.cleanData( [ elem ], true );
+
+	// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
+	} else if ( jQuery.support.deleteExpando || cache != cache.window ) {
+		delete cache[ id ];
+
+	// When all else fails, null
+	} else {
+		cache[ id ] = null;
+	}
+}
+
+jQuery.extend({
+	cache: {},
+
+	// Unique for each copy of jQuery on the page
+	// Non-digits removed to match rinlinejQuery
+	expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),
+
+	// The following elements throw uncatchable exceptions if you
+	// attempt to add expando properties to them.
+	noData: {
+		"embed": true,
+		// Ban all objects except for Flash (which handle expandos)
+		"object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
+		"applet": true
+	},
+
+	hasData: function( elem ) {
+		elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
+		return !!elem && !isEmptyDataObject( elem );
+	},
+
+	data: function( elem, name, data ) {
+		return internalData( elem, name, data );
+	},
+
+	removeData: function( elem, name ) {
+		return internalRemoveData( elem, name );
+	},
+
+	// For internal use only.
+	_data: function( elem, name, data ) {
+		return internalData( elem, name, data, true );
+	},
+
+	_removeData: function( elem, name ) {
+		return internalRemoveData( elem, name, true );
+	},
+
+	// A method for determining if a DOM node can handle the data expando
+	acceptData: function( elem ) {
+		// Do not set data on non-element because it will not be cleared (#8335).
+		if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) {
+			return false;
+		}
+
+		var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
+
+		// nodes accept data unless otherwise specified; rejection can be conditional
+		return !noData || noData !== true && elem.getAttribute("classid") === noData;
+	}
+});
+
+jQuery.fn.extend({
+	data: function( key, value ) {
+		var attrs, name,
+			elem = this[0],
+			i = 0,
+			data = null;
+
+		// Gets all values
+		if ( key === undefined ) {
+			if ( this.length ) {
+				data = jQuery.data( elem );
+
+				if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
+					attrs = elem.attributes;
+					for ( ; i < attrs.length; i++ ) {
+						name = attrs[i].name;
+
+						if ( !name.indexOf( "data-" ) ) {
+							name = jQuery.camelCase( name.slice(5) );
+
+							dataAttr( elem, name, data[ name ] );
+						}
+					}
+					jQuery._data( elem, "parsedAttrs", true );
+				}
+			}
+
+			return data;
+		}
+
+		// Sets multiple values
+		if ( typeof key === "object" ) {
+			return this.each(function() {
+				jQuery.data( this, key );
+			});
+		}
+
+		return jQuery.access( this, function( value ) {
+
+			if ( value === undefined ) {
+				// Try to fetch any internally stored data first
+				return elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null;
+			}
+
+			this.each(function() {
+				jQuery.data( this, key, value );
+			});
+		}, null, value, arguments.length > 1, null, true );
+	},
+
+	removeData: function( key ) {
+		return this.each(function() {
+			jQuery.removeData( this, key );
+		});
+	}
+});
+
+function dataAttr( elem, key, data ) {
+	// If nothing was found internally, try to fetch any
+	// data from the HTML5 data-* attribute
+	if ( data === undefined && elem.nodeType === 1 ) {
+
+		var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
+
+		data = elem.getAttribute( name );
+
+		if ( typeof data === "string" ) {
+			try {
+				data = data === "true" ? true :
+					data === "false" ? false :
+					data === "null" ? null :
+					// Only convert to a number if it doesn't change the string
+					+data + "" === data ? +data :
+					rbrace.test( data ) ? jQuery.parseJSON( data ) :
+						data;
+			} catch( e ) {}
+
+			// Make sure we set the data so it isn't changed later
+			jQuery.data( elem, key, data );
+
+		} else {
+			data = undefined;
+		}
+	}
+
+	return data;
+}
+
+// checks a cache object for emptiness
+function isEmptyDataObject( obj ) {
+	var name;
+	for ( name in obj ) {
+
+		// if the public data object is empty, the private is still empty
+		if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
+			continue;
+		}
+		if ( name !== "toJSON" ) {
+			return false;
+		}
+	}
+
+	return true;
+}
+jQuery.extend({
+	queue: function( elem, type, data ) {
+		var queue;
+
+		if ( elem ) {
+			type = ( type || "fx" ) + "queue";
+			queue = jQuery._data( elem, type );
+
+			// Speed up dequeue by getting out quickly if this is just a lookup
+			if ( data ) {
+				if ( !queue || jQuery.isArray(data) ) {
+					queue = jQuery._data( elem, type, jQuery.makeArray(data) );
+				} else {
+					queue.push( data );
+				}
+			}
+			return queue || [];
+		}
+	},
+
+	dequeue: function( elem, type ) {
+		type = type || "fx";
+
+		var queue = jQuery.queue( elem, type ),
+			startLength = queue.length,
+			fn = queue.shift(),
+			hooks = jQuery._queueHooks( elem, type ),
+			next = function() {
+				jQuery.dequeue( elem, type );
+			};
+
+		// If the fx queue is dequeued, always remove the progress sentinel
+		if ( fn === "inprogress" ) {
+			fn = queue.shift();
+			startLength--;
+		}
+
+		hooks.cur = fn;
+		if ( fn ) {
+
+			// Add a progress sentinel to prevent the fx queue from being
+			// automatically dequeued
+			if ( type === "fx" ) {
+				queue.unshift( "inprogress" );
+			}
+
+			// clear up the last queue stop function
+			delete hooks.stop;
+			fn.call( elem, next, hooks );
+		}
+
+		if ( !startLength && hooks ) {
+			hooks.empty.fire();
+		}
+	},
+
+	// not intended for public consumption - generates a queueHooks object, or returns the current one
+	_queueHooks: function( elem, type ) {
+		var key = type + "queueHooks";
+		return jQuery._data( elem, key ) || jQuery._data( elem, key, {
+			empty: jQuery.Callbacks("once memory").add(function() {
+				jQuery._removeData( elem, type + "queue" );
+				jQuery._removeData( elem, key );
+			})
+		});
+	}
+});
+
+jQuery.fn.extend({
+	queue: function( type, data ) {
+		var setter = 2;
+
+		if ( typeof type !== "string" ) {
+			data = type;
+			type = "fx";
+			setter--;
+		}
+
+		if ( arguments.length < setter ) {
+			return jQuery.queue( this[0], type );
+		}
+
+		return data === undefined ?
+			this :
+			this.each(function() {
+				var queue = jQuery.queue( this, type, data );
+
+				// ensure a hooks for this queue
+				jQuery._queueHooks( this, type );
+
+				if ( type === "fx" && queue[0] !== "inprogress" ) {
+					jQuery.dequeue( this, type );
+				}
+			});
+	},
+	dequeue: function( type ) {
+		return this.each(function() {
+			jQuery.dequeue( this, type );
+		});
+	},
+	// Based off of the plugin by Clint Helfers, with permission.
+	// http://blindsignals.com/index.php/2009/07/jquery-delay/
+	delay: function( time, type ) {
+		time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
+		type = type || "fx";
+
+		return this.queue( type, function( next, hooks ) {
+			var timeout = setTimeout( next, time );
+			hooks.stop = function() {
+				clearTimeout( timeout );
+			};
+		});
+	},
+	clearQueue: function( type ) {
+		return this.queue( type || "fx", [] );
+	},
+	// Get a promise resolved when queues of a certain type
+	// are emptied (fx is the type by default)
+	promise: function( type, obj ) {
+		var tmp,
+			count = 1,
+			defer = jQuery.Deferred(),
+			elements = this,
+			i = this.length,
+			resolve = function() {
+				if ( !( --count ) ) {
+					defer.resolveWith( elements, [ elements ] );
+				}
+			};
+
+		if ( typeof type !== "string" ) {
+			obj = type;
+			type = undefined;
+		}
+		type = type || "fx";
+
+		while( i-- ) {
+			tmp = jQuery._data( elements[ i ], type + "queueHooks" );
+			if ( tmp && tmp.empty ) {
+				count++;
+				tmp.empty.add( resolve );
+			}
+		}
+		resolve();
+		return defer.promise( obj );
+	}
+});
+var nodeHook, boolHook,
+	rclass = /[\t\r\n]/g,
+	rreturn = /\r/g,
+	rfocusable = /^(?:input|select|textarea|button|object)$/i,
+	rclickable = /^(?:a|area)$/i,
+	rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,
+	ruseDefault = /^(?:checked|selected)$/i,
+	getSetAttribute = jQuery.support.getSetAttribute,
+	getSetInput = jQuery.support.input;
+
+jQuery.fn.extend({
+	attr: function( name, value ) {
+		return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
+	},
+
+	removeAttr: function( name ) {
+		return this.each(function() {
+			jQuery.removeAttr( this, name );
+		});
+	},
+
+	prop: function( name, value ) {
+		return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
+	},
+
+	removeProp: function( name ) {
+		name = jQuery.propFix[ name ] || name;
+		return this.each(function() {
+			// try/catch handles cases where IE balks (such as removing a property on window)
+			try {
+				this[ name ] = undefined;
+				delete this[ name ];
+			} catch( e ) {}
+		});
+	},
+
+	addClass: function( value ) {
+		var classes, elem, cur, clazz, j,
+			i = 0,
+			len = this.length,
+			proceed = typeof value === "string" && value;
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function( j ) {
+				jQuery( this ).addClass( value.call( this, j, this.className ) );
+			});
+		}
+
+		if ( proceed ) {
+			// The disjunction here is for better compressibility (see removeClass)
+			classes = ( value || "" ).match( core_rnotwhite ) || [];
+
+			for ( ; i < len; i++ ) {
+				elem = this[ i ];
+				cur = elem.nodeType === 1 && ( elem.className ?
+					( " " + elem.className + " " ).replace( rclass, " " ) :
+					" "
+				);
+
+				if ( cur ) {
+					j = 0;
+					while ( (clazz = classes[j++]) ) {
+						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
+							cur += clazz + " ";
+						}
+					}
+					elem.className = jQuery.trim( cur );
+
+				}
+			}
+		}
+
+		return this;
+	},
+
+	removeClass: function( value ) {
+		var classes, elem, cur, clazz, j,
+			i = 0,
+			len = this.length,
+			proceed = arguments.length === 0 || typeof value === "string" && value;
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function( j ) {
+				jQuery( this ).removeClass( value.call( this, j, this.className ) );
+			});
+		}
+		if ( proceed ) {
+			classes = ( value || "" ).match( core_rnotwhite ) || [];
+
+			for ( ; i < len; i++ ) {
+				elem = this[ i ];
+				// This expression is here for better compressibility (see addClass)
+				cur = elem.nodeType === 1 && ( elem.className ?
+					( " " + elem.className + " " ).replace( rclass, " " ) :
+					""
+				);
+
+				if ( cur ) {
+					j = 0;
+					while ( (clazz = classes[j++]) ) {
+						// Remove *all* instances
+						while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
+							cur = cur.replace( " " + clazz + " ", " " );
+						}
+					}
+					elem.className = value ? jQuery.trim( cur ) : "";
+				}
+			}
+		}
+
+		return this;
+	},
+
+	toggleClass: function( value, stateVal ) {
+		var type = typeof value,
+			isBool = typeof stateVal === "boolean";
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function( i ) {
+				jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
+			});
+		}
+
+		return this.each(function() {
+			if ( type === "string" ) {
+				// toggle individual class names
+				var className,
+					i = 0,
+					self = jQuery( this ),
+					state = stateVal,
+					classNames = value.match( core_rnotwhite ) || [];
+
+				while ( (className = classNames[ i++ ]) ) {
+					// check each className given, space separated list
+					state = isBool ? state : !self.hasClass( className );
+					self[ state ? "addClass" : "removeClass" ]( className );
+				}
+
+			// Toggle whole class name
+			} else if ( type === core_strundefined || type === "boolean" ) {
+				if ( this.className ) {
+					// store className if set
+					jQuery._data( this, "__className__", this.className );
+				}
+
+				// If the element has a class name or if we're passed "false",
+				// then remove the whole classname (if there was one, the above saved it).
+				// Otherwise bring back whatever was previously saved (if anything),
+				// falling back to the empty string if nothing was stored.
+				this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
+			}
+		});
+	},
+
+	hasClass: function( selector ) {
+		var className = " " + selector + " ",
+			i = 0,
+			l = this.length;
+		for ( ; i < l; i++ ) {
+			if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
+				return true;
+			}
+		}
+
+		return false;
+	},
+
+	val: function( value ) {
+		var ret, hooks, isFunction,
+			elem = this[0];
+
+		if ( !arguments.length ) {
+			if ( elem ) {
+				hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
+
+				if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
+					return ret;
+				}
+
+				ret = elem.value;
+
+				return typeof ret === "string" ?
+					// handle most common string cases
+					ret.replace(rreturn, "") :
+					// handle cases where value is null/undef or number
+					ret == null ? "" : ret;
+			}
+
+			return;
+		}
+
+		isFunction = jQuery.isFunction( value );
+
+		return this.each(function( i ) {
+			var val,
+				self = jQuery(this);
+
+			if ( this.nodeType !== 1 ) {
+				return;
+			}
+
+			if ( isFunction ) {
+				val = value.call( this, i, self.val() );
+			} else {
+				val = value;
+			}
+
+			// Treat null/undefined as ""; convert numbers to string
+			if ( val == null ) {
+				val = "";
+			} else if ( typeof val === "number" ) {
+				val += "";
+			} else if ( jQuery.isArray( val ) ) {
+				val = jQuery.map(val, function ( value ) {
+					return value == null ? "" : value + "";
+				});
+			}
+
+			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
+
+			// If set returns undefined, fall back to normal setting
+			if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
+				this.value = val;
+			}
+		});
+	}
+});
+
+jQuery.extend({
+	valHooks: {
+		option: {
+			get: function( elem ) {
+				// attributes.value is undefined in Blackberry 4.7 but
+				// uses .value. See #6932
+				var val = elem.attributes.value;
+				return !val || val.specified ? elem.value : elem.text;
+			}
+		},
+		select: {
+			get: function( elem ) {
+				var value, option,
+					options = elem.options,
+					index = elem.selectedIndex,
+					one = elem.type === "select-one" || index < 0,
+					values = one ? null : [],
+					max = one ? index + 1 : options.length,
+					i = index < 0 ?
+						max :
+						one ? index : 0;
+
+				// Loop through all the selected options
+				for ( ; i < max; i++ ) {
+					option = options[ i ];
+
+					// oldIE doesn't update selected after form reset (#2551)
+					if ( ( option.selected || i === index ) &&
+							// Don't return options that are disabled or in a disabled optgroup
+							( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
+							( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
+
+						// Get the specific value for the option
+						value = jQuery( option ).val();
+
+						// We don't need an array for one selects
+						if ( one ) {
+							return value;
+						}
+
+						// Multi-Selects return an array
+						values.push( value );
+					}
+				}
+
+				return values;
+			},
+
+			set: function( elem, value ) {
+				var values = jQuery.makeArray( value );
+
+				jQuery(elem).find("option").each(function() {
+					this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+				});
+
+				if ( !values.length ) {
+					elem.selectedIndex = -1;
+				}
+				return values;
+			}
+		}
+	},
+
+	attr: function( elem, name, value ) {
+		var hooks, notxml, ret,
+			nType = elem.nodeType;
+
+		// don't get/set attributes on text, comment and attribute nodes
+		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+			return;
+		}
+
+		// Fallback to prop when attributes are not supported
+		if ( typeof elem.getAttribute === core_strundefined ) {
+			return jQuery.prop( elem, name, value );
+		}
+
+		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+		// All attributes are lowercase
+		// Grab necessary hook if one is defined
+		if ( notxml ) {
+			name = name.toLowerCase();
+			hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
+		}
+
+		if ( value !== undefined ) {
+
+			if ( value === null ) {
+				jQuery.removeAttr( elem, name );
+
+			} else if ( hooks && notxml && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+				return ret;
+
+			} else {
+				elem.setAttribute( name, value + "" );
+				return value;
+			}
+
+		} else if ( hooks && notxml && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
+			return ret;
+
+		} else {
+
+			// In IE9+, Flash objects don't have .getAttribute (#12945)
+			// Support: IE9+
+			if ( typeof elem.getAttribute !== core_strundefined ) {
+				ret =  elem.getAttribute( name );
+			}
+
+			// Non-existent attributes return null, we normalize to undefined
+			return ret == null ?
+				undefined :
+				ret;
+		}
+	},
+
+	removeAttr: function( elem, value ) {
+		var name, propName,
+			i = 0,
+			attrNames = value && value.match( core_rnotwhite );
+
+		if ( attrNames && elem.nodeType === 1 ) {
+			while ( (name = attrNames[i++]) ) {
+				propName = jQuery.propFix[ name ] || name;
+
+				// Boolean attributes get special treatment (#10870)
+				if ( rboolean.test( name ) ) {
+					// Set corresponding property to false for boolean attributes
+					// Also clear defaultChecked/defaultSelected (if appropriate) for IE<8
+					if ( !getSetAttribute && ruseDefault.test( name ) ) {
+						elem[ jQuery.camelCase( "default-" + name ) ] =
+							elem[ propName ] = false;
+					} else {
+						elem[ propName ] = false;
+					}
+
+				// See #9699 for explanation of this approach (setting first, then removal)
+				} else {
+					jQuery.attr( elem, name, "" );
+				}
+
+				elem.removeAttribute( getSetAttribute ? name : propName );
+			}
+		}
+	},
+
+	attrHooks: {
+		type: {
+			set: function( elem, value ) {
+				if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
+					// Setting the type on a radio button after the value resets the value in IE6-9
+					// Reset value to default in case type is set after value during creation
+					var val = elem.value;
+					elem.setAttribute( "type", value );
+					if ( val ) {
+						elem.value = val;
+					}
+					return value;
+				}
+			}
+		}
+	},
+
+	propFix: {
+		tabindex: "tabIndex",
+		readonly: "readOnly",
+		"for": "htmlFor",
+		"class": "className",
+		maxlength: "maxLength",
+		cellspacing: "cellSpacing",
+		cellpadding: "cellPadding",
+		rowspan: "rowSpan",
+		colspan: "colSpan",
+		usemap: "useMap",
+		frameborder: "frameBorder",
+		contenteditable: "contentEditable"
+	},
+
+	prop: function( elem, name, value ) {
+		var ret, hooks, notxml,
+			nType = elem.nodeType;
+
+		// don't get/set properties on text, comment and attribute nodes
+		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+			return;
+		}
+
+		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+		if ( notxml ) {
+			// Fix name and attach hooks
+			name = jQuery.propFix[ name ] || name;
+			hooks = jQuery.propHooks[ name ];
+		}
+
+		if ( value !== undefined ) {
+			if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+				return ret;
+
+			} else {
+				return ( elem[ name ] = value );
+			}
+
+		} else {
+			if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
+				return ret;
+
+			} else {
+				return elem[ name ];
+			}
+		}
+	},
+
+	propHooks: {
+		tabIndex: {
+			get: function( elem ) {
+				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+				var attributeNode = elem.getAttributeNode("tabindex");
+
+				return attributeNode && attributeNode.specified ?
+					parseInt( attributeNode.value, 10 ) :
+					rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+						0 :
+						undefined;
+			}
+		}
+	}
+});
+
+// Hook for boolean attributes
+boolHook = {
+	get: function( elem, name ) {
+		var
+			// Use .prop to determine if this attribute is understood as boolean
+			prop = jQuery.prop( elem, name ),
+
+			// Fetch it accordingly
+			attr = typeof prop === "boolean" && elem.getAttribute( name ),
+			detail = typeof prop === "boolean" ?
+
+				getSetInput && getSetAttribute ?
+					attr != null :
+					// oldIE fabricates an empty string for missing boolean attributes
+					// and conflates checked/selected into attroperties
+					ruseDefault.test( name ) ?
+						elem[ jQuery.camelCase( "default-" + name ) ] :
+						!!attr :
+
+				// fetch an attribute node for properties not recognized as boolean
+				elem.getAttributeNode( name );
+
+		return detail && detail.value !== false ?
+			name.toLowerCase() :
+			undefined;
+	},
+	set: function( elem, value, name ) {
+		if ( value === false ) {
+			// Remove boolean attributes when set to false
+			jQuery.removeAttr( elem, name );
+		} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
+			// IE<8 needs the *property* name
+			elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
+
+		// Use defaultChecked and defaultSelected for oldIE
+		} else {
+			elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
+		}
+
+		return name;
+	}
+};
+
+// fix oldIE value attroperty
+if ( !getSetInput || !getSetAttribute ) {
+	jQuery.attrHooks.value = {
+		get: function( elem, name ) {
+			var ret = elem.getAttributeNode( name );
+			return jQuery.nodeName( elem, "input" ) ?
+
+				// Ignore the value *property* by using defaultValue
+				elem.defaultValue :
+
+				ret && ret.specified ? ret.value : undefined;
+		},
+		set: function( elem, value, name ) {
+			if ( jQuery.nodeName( elem, "input" ) ) {
+				// Does not return so that setAttribute is also used
+				elem.defaultValue = value;
+			} else {
+				// Use nodeHook if defined (#1954); otherwise setAttribute is fine
+				return nodeHook && nodeHook.set( elem, value, name );
+			}
+		}
+	};
+}
+
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
+if ( !getSetAttribute ) {
+
+	// Use this for any attribute in IE6/7
+	// This fixes almost every IE6/7 issue
+	nodeHook = jQuery.valHooks.button = {
+		get: function( elem, name ) {
+			var ret = elem.getAttributeNode( name );
+			return ret && ( name === "id" || name === "name" || name === "coords" ? ret.value !== "" : ret.specified ) ?
+				ret.value :
+				undefined;
+		},
+		set: function( elem, value, name ) {
+			// Set the existing or create a new attribute node
+			var ret = elem.getAttributeNode( name );
+			if ( !ret ) {
+				elem.setAttributeNode(
+					(ret = elem.ownerDocument.createAttribute( name ))
+				);
+			}
+
+			ret.value = value += "";
+
+			// Break association with cloned elements by also using setAttribute (#9646)
+			return name === "value" || value === elem.getAttribute( name ) ?
+				value :
+				undefined;
+		}
+	};
+
+	// Set contenteditable to false on removals(#10429)
+	// Setting to empty string throws an error as an invalid value
+	jQuery.attrHooks.contenteditable = {
+		get: nodeHook.get,
+		set: function( elem, value, name ) {
+			nodeHook.set( elem, value === "" ? false : value, name );
+		}
+	};
+
+	// Set width and height to auto instead of 0 on empty string( Bug #8150 )
+	// This is for removals
+	jQuery.each([ "width", "height" ], function( i, name ) {
+		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+			set: function( elem, value ) {
+				if ( value === "" ) {
+					elem.setAttribute( name, "auto" );
+					return value;
+				}
+			}
+		});
+	});
+}
+
+
+// Some attributes require a special call on IE
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !jQuery.support.hrefNormalized ) {
+	jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
+		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+			get: function( elem ) {
+				var ret = elem.getAttribute( name, 2 );
+				return ret == null ? undefined : ret;
+			}
+		});
+	});
+
+	// href/src property should get the full normalized URL (#10299/#12915)
+	jQuery.each([ "href", "src" ], function( i, name ) {
+		jQuery.propHooks[ name ] = {
+			get: function( elem ) {
+				return elem.getAttribute( name, 4 );
+			}
+		};
+	});
+}
+
+if ( !jQuery.support.style ) {
+	jQuery.attrHooks.style = {
+		get: function( elem ) {
+			// Return undefined in the case of empty string
+			// Note: IE uppercases css property names, but if we were to .toLowerCase()
+			// .cssText, that would destroy case senstitivity in URL's, like in "background"
+			return elem.style.cssText || undefined;
+		},
+		set: function( elem, value ) {
+			return ( elem.style.cssText = value + "" );
+		}
+	};
+}
+
+// Safari mis-reports the default selected property of an option
+// Accessing the parent's selectedIndex property fixes it
+if ( !jQuery.support.optSelected ) {
+	jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
+		get: function( elem ) {
+			var parent = elem.parentNode;
+
+			if ( parent ) {
+				parent.selectedIndex;
+
+				// Make sure that it also works with optgroups, see #5701
+				if ( parent.parentNode ) {
+					parent.parentNode.selectedIndex;
+				}
+			}
+			return null;
+		}
+	});
+}
+
+// IE6/7 call enctype encoding
+if ( !jQuery.support.enctype ) {
+	jQuery.propFix.enctype = "encoding";
+}
+
+// Radios and checkboxes getter/setter
+if ( !jQuery.support.checkOn ) {
+	jQuery.each([ "radio", "checkbox" ], function() {
+		jQuery.valHooks[ this ] = {
+			get: function( elem ) {
+				// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+				return elem.getAttribute("value") === null ? "on" : elem.value;
+			}
+		};
+	});
+}
+jQuery.each([ "radio", "checkbox" ], function() {
+	jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
+		set: function( elem, value ) {
+			if ( jQuery.isArray( value ) ) {
+				return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
+			}
+		}
+	});
+});
+var rformElems = /^(?:input|select|textarea)$/i,
+	rkeyEvent = /^key/,
+	rmouseEvent = /^(?:mouse|contextmenu)|click/,
+	rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
+	rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
+
+function returnTrue() {
+	return true;
+}
+
+function returnFalse() {
+	return false;
+}
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
+
+	global: {},
+
+	add: function( elem, types, handler, data, selector ) {
+		var tmp, events, t, handleObjIn,
+			special, eventHandle, handleObj,
+			handlers, type, namespaces, origType,
+			elemData = jQuery._data( elem );
+
+		// Don't attach events to noData or text/comment nodes (but allow plain objects)
+		if ( !elemData ) {
+			return;
+		}
+
+		// Caller can pass in an object of custom data in lieu of the handler
+		if ( handler.handler ) {
+			handleObjIn = handler;
+			handler = handleObjIn.handler;
+			selector = handleObjIn.selector;
+		}
+
+		// Make sure that the handler has a unique ID, used to find/remove it later
+		if ( !handler.guid ) {
+			handler.guid = jQuery.guid++;
+		}
+
+		// Init the element's event structure and main handler, if this is the first
+		if ( !(events = elemData.events) ) {
+			events = elemData.events = {};
+		}
+		if ( !(eventHandle = elemData.handle) ) {
+			eventHandle = elemData.handle = function( e ) {
+				// Discard the second event of a jQuery.event.trigger() and
+				// when an event is called after a page has unloaded
+				return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?
+					jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
+					undefined;
+			};
+			// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
+			eventHandle.elem = elem;
+		}
+
+		// Handle multiple events separated by a space
+		// jQuery(...).bind("mouseover mouseout", fn);
+		types = ( types || "" ).match( core_rnotwhite ) || [""];
+		t = types.length;
+		while ( t-- ) {
+			tmp = rtypenamespace.exec( types[t] ) || [];
+			type = origType = tmp[1];
+			namespaces = ( tmp[2] || "" ).split( "." ).sort();
+
+			// If event changes its type, use the special event handlers for the changed type
+			special = jQuery.event.special[ type ] || {};
+
+			// If selector defined, determine special event api type, otherwise given type
+			type = ( selector ? special.delegateType : special.bindType ) || type;
+
+			// Update special based on newly reset type
+			special = jQuery.event.special[ type ] || {};
+
+			// handleObj is passed to all event handlers
+			handleObj = jQuery.extend({
+				type: type,
+				origType: origType,
+				data: data,
+				handler: handler,
+				guid: handler.guid,
+				selector: selector,
+				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
+				namespace: namespaces.join(".")
+			}, handleObjIn );
+
+			// Init the event handler queue if we're the first
+			if ( !(handlers = events[ type ]) ) {
+				handlers = events[ type ] = [];
+				handlers.delegateCount = 0;
+
+				// Only use addEventListener/attachEvent if the special events handler returns false
+				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+					// Bind the global event handler to the element
+					if ( elem.addEventListener ) {
+						elem.addEventListener( type, eventHandle, false );
+
+					} else if ( elem.attachEvent ) {
+						elem.attachEvent( "on" + type, eventHandle );
+					}
+				}
+			}
+
+			if ( special.add ) {
+				special.add.call( elem, handleObj );
+
+				if ( !handleObj.handler.guid ) {
+					handleObj.handler.guid = handler.guid;
+				}
+			}
+
+			// Add to the element's handler list, delegates in front
+			if ( selector ) {
+				handlers.splice( handlers.delegateCount++, 0, handleObj );
+			} else {
+				handlers.push( handleObj );
+			}
+
+			// Keep track of which events have ever been used, for event optimization
+			jQuery.event.global[ type ] = true;
+		}
+
+		// Nullify elem to prevent memory leaks in IE
+		elem = null;
+	},
+
+	// Detach an event or set of events from an element
+	remove: function( elem, types, handler, selector, mappedTypes ) {
+		var j, handleObj, tmp,
+			origCount, t, events,
+			special, handlers, type,
+			namespaces, origType,
+			elemData = jQuery.hasData( elem ) && jQuery._data( elem );
+
+		if ( !elemData || !(events = elemData.events) ) {
+			return;
+		}
+
+		// Once for each type.namespace in types; type may be omitted
+		types = ( types || "" ).match( core_rnotwhite ) || [""];
+		t = types.length;
+		while ( t-- ) {
+			tmp = rtypenamespace.exec( types[t] ) || [];
+			type = origType = tmp[1];
+			namespaces = ( tmp[2] || "" ).split( "." ).sort();
+
+			// Unbind all events (on this namespace, if provided) for the element
+			if ( !type ) {
+				for ( type in events ) {
+					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
+				}
+				continue;
+			}
+
+			special = jQuery.event.special[ type ] || {};
+			type = ( selector ? special.delegateType : special.bindType ) || type;
+			handlers = events[ type ] || [];
+			tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
+
+			// Remove matching events
+			origCount = j = handlers.length;
+			while ( j-- ) {
+				handleObj = handlers[ j ];
+
+				if ( ( mappedTypes || origType === handleObj.origType ) &&
+					( !handler || handler.guid === handleObj.guid ) &&
+					( !tmp || tmp.test( handleObj.namespace ) ) &&
+					( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
+					handlers.splice( j, 1 );
+
+					if ( handleObj.selector ) {
+						handlers.delegateCount--;
+					}
+					if ( special.remove ) {
+						special.remove.call( elem, handleObj );
+					}
+				}
+			}
+
+			// Remove generic event handler if we removed something and no more handlers exist
+			// (avoids potential for endless recursion during removal of special event handlers)
+			if ( origCount && !handlers.length ) {
+				if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+					jQuery.removeEvent( elem, type, elemData.handle );
+				}
+
+				delete events[ type ];
+			}
+		}
+
+		// Remove the expando if it's no longer used
+		if ( jQuery.isEmptyObject( events ) ) {
+			delete elemData.handle;
+
+			// removeData also checks for emptiness and clears the expando if empty
+			// so use it instead of delete
+			jQuery._removeData( elem, "events" );
+		}
+	},
+
+	trigger: function( event, data, elem, onlyHandlers ) {
+		var handle, ontype, cur,
+			bubbleType, special, tmp, i,
+			eventPath = [ elem || document ],
+			type = core_hasOwn.call( event, "type" ) ? event.type : event,
+			namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
+
+		cur = tmp = elem = elem || document;
+
+		// Don't do events on text and comment nodes
+		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return;
+		}
+
+		// focus/blur morphs to focusin/out; ensure we're not firing them right now
+		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
+			return;
+		}
+
+		if ( type.indexOf(".") >= 0 ) {
+			// Namespaced trigger; create a regexp to match event type in handle()
+			namespaces = type.split(".");
+			type = namespaces.shift();
+			namespaces.sort();
+		}
+		ontype = type.indexOf(":") < 0 && "on" + type;
+
+		// Caller can pass in a jQuery.Event object, Object, or just an event type string
+		event = event[ jQuery.expando ] ?
+			event :
+			new jQuery.Event( type, typeof event === "object" && event );
+
+		event.isTrigger = true;
+		event.namespace = namespaces.join(".");
+		event.namespace_re = event.namespace ?
+			new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
+			null;
+
+		// Clean up the event in case it is being reused
+		event.result = undefined;
+		if ( !event.target ) {
+			event.target = elem;
+		}
+
+		// Clone any incoming data and prepend the event, creating the handler arg list
+		data = data == null ?
+			[ event ] :
+			jQuery.makeArray( data, [ event ] );
+
+		// Allow special events to draw outside the lines
+		special = jQuery.event.special[ type ] || {};
+		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
+			return;
+		}
+
+		// Determine event propagation path in advance, per W3C events spec (#9951)
+		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
+		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
+
+			bubbleType = special.delegateType || type;
+			if ( !rfocusMorph.test( bubbleType + type ) ) {
+				cur = cur.parentNode;
+			}
+			for ( ; cur; cur = cur.parentNode ) {
+				eventPath.push( cur );
+				tmp = cur;
+			}
+
+			// Only add window if we got to document (e.g., not plain obj or detached DOM)
+			if ( tmp === (elem.ownerDocument || document) ) {
+				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
+			}
+		}
+
+		// Fire handlers on the event path
+		i = 0;
+		while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
+
+			event.type = i > 1 ?
+				bubbleType :
+				special.bindType || type;
+
+			// jQuery handler
+			handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
+			if ( handle ) {
+				handle.apply( cur, data );
+			}
+
+			// Native handler
+			handle = ontype && cur[ ontype ];
+			if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
+				event.preventDefault();
+			}
+		}
+		event.type = type;
+
+		// If nobody prevented the default action, do it now
+		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
+
+			if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&
+				!(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
+
+				// Call a native DOM method on the target with the same name name as the event.
+				// Can't use an .isFunction() check here because IE6/7 fails that test.
+				// Don't do default actions on window, that's where global variables be (#6170)
+				if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
+
+					// Don't re-trigger an onFOO event when we call its FOO() method
+					tmp = elem[ ontype ];
+
+					if ( tmp ) {
+						elem[ ontype ] = null;
+					}
+
+					// Prevent re-triggering of the same event, since we already bubbled it above
+					jQuery.event.triggered = type;
+					try {
+						elem[ type ]();
+					} catch ( e ) {
+						// IE<9 dies on focus/blur to hidden element (#1486,#12518)
+						// only reproducible on winXP IE8 native, not IE9 in IE8 mode
+					}
+					jQuery.event.triggered = undefined;
+
+					if ( tmp ) {
+						elem[ ontype ] = tmp;
+					}
+				}
+			}
+		}
+
+		return event.result;
+	},
+
+	dispatch: function( event ) {
+
+		// Make a writable jQuery.Event from the native event object
+		event = jQuery.event.fix( event );
+
+		var i, ret, handleObj, matched, j,
+			handlerQueue = [],
+			args = core_slice.call( arguments ),
+			handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
+			special = jQuery.event.special[ event.type ] || {};
+
+		// Use the fix-ed jQuery.Event rather than the (read-only) native event
+		args[0] = event;
+		event.delegateTarget = this;
+
+		// Call the preDispatch hook for the mapped type, and let it bail if desired
+		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
+			return;
+		}
+
+		// Determine handlers
+		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
+
+		// Run delegates first; they may want to stop propagation beneath us
+		i = 0;
+		while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
+			event.currentTarget = matched.elem;
+
+			j = 0;
+			while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
+
+				// Triggered event must either 1) have no namespace, or
+				// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
+				if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
+
+					event.handleObj = handleObj;
+					event.data = handleObj.data;
+
+					ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
+							.apply( matched.elem, args );
+
+					if ( ret !== undefined ) {
+						if ( (event.result = ret) === false ) {
+							event.preventDefault();
+							event.stopPropagation();
+						}
+					}
+				}
+			}
+		}
+
+		// Call the postDispatch hook for the mapped type
+		if ( special.postDispatch ) {
+			special.postDispatch.call( this, event );
+		}
+
+		return event.result;
+	},
+
+	handlers: function( event, handlers ) {
+		var sel, handleObj, matches, i,
+			handlerQueue = [],
+			delegateCount = handlers.delegateCount,
+			cur = event.target;
+
+		// Find delegate handlers
+		// Black-hole SVG <use> instance trees (#13180)
+		// Avoid non-left-click bubbling in Firefox (#3861)
+		if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
+
+			for ( ; cur != this; cur = cur.parentNode || this ) {
+
+				// Don't check non-elements (#13208)
+				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
+				if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
+					matches = [];
+					for ( i = 0; i < delegateCount; i++ ) {
+						handleObj = handlers[ i ];
+
+						// Don't conflict with Object.prototype properties (#13203)
+						sel = handleObj.selector + " ";
+
+						if ( matches[ sel ] === undefined ) {
+							matches[ sel ] = handleObj.needsContext ?
+								jQuery( sel, this ).index( cur ) >= 0 :
+								jQuery.find( sel, this, null, [ cur ] ).length;
+						}
+						if ( matches[ sel ] ) {
+							matches.push( handleObj );
+						}
+					}
+					if ( matches.length ) {
+						handlerQueue.push({ elem: cur, handlers: matches });
+					}
+				}
+			}
+		}
+
+		// Add the remaining (directly-bound) handlers
+		if ( delegateCount < handlers.length ) {
+			handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
+		}
+
+		return handlerQueue;
+	},
+
+	fix: function( event ) {
+		if ( event[ jQuery.expando ] ) {
+			return event;
+		}
+
+		// Create a writable copy of the event object and normalize some properties
+		var i, prop, copy,
+			type = event.type,
+			originalEvent = event,
+			fixHook = this.fixHooks[ type ];
+
+		if ( !fixHook ) {
+			this.fixHooks[ type ] = fixHook =
+				rmouseEvent.test( type ) ? this.mouseHooks :
+				rkeyEvent.test( type ) ? this.keyHooks :
+				{};
+		}
+		copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
+
+		event = new jQuery.Event( originalEvent );
+
+		i = copy.length;
+		while ( i-- ) {
+			prop = copy[ i ];
+			event[ prop ] = originalEvent[ prop ];
+		}
+
+		// Support: IE<9
+		// Fix target property (#1925)
+		if ( !event.target ) {
+			event.target = originalEvent.srcElement || document;
+		}
+
+		// Support: Chrome 23+, Safari?
+		// Target should not be a text node (#504, #13143)
+		if ( event.target.nodeType === 3 ) {
+			event.target = event.target.parentNode;
+		}
+
+		// Support: IE<9
+		// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
+		event.metaKey = !!event.metaKey;
+
+		return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
+	},
+
+	// Includes some event props shared by KeyEvent and MouseEvent
+	props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
+
+	fixHooks: {},
+
+	keyHooks: {
+		props: "char charCode key keyCode".split(" "),
+		filter: function( event, original ) {
+
+			// Add which for key events
+			if ( event.which == null ) {
+				event.which = original.charCode != null ? original.charCode : original.keyCode;
+			}
+
+			return event;
+		}
+	},
+
+	mouseHooks: {
+		props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
+		filter: function( event, original ) {
+			var body, eventDoc, doc,
+				button = original.button,
+				fromElement = original.fromElement;
+
+			// Calculate pageX/Y if missing and clientX/Y available
+			if ( event.pageX == null && original.clientX != null ) {
+				eventDoc = event.target.ownerDocument || document;
+				doc = eventDoc.documentElement;
+				body = eventDoc.body;
+
+				event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
+				event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
+			}
+
+			// Add relatedTarget, if necessary
+			if ( !event.relatedTarget && fromElement ) {
+				event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
+			}
+
+			// Add which for click: 1 === left; 2 === middle; 3 === right
+			// Note: button is not normalized, so don't use it
+			if ( !event.which && button !== undefined ) {
+				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
+			}
+
+			return event;
+		}
+	},
+
+	special: {
+		load: {
+			// Prevent triggered image.load events from bubbling to window.load
+			noBubble: true
+		},
+		click: {
+			// For checkbox, fire native event so checked state will be right
+			trigger: function() {
+				if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
+					this.click();
+					return false;
+				}
+			}
+		},
+		focus: {
+			// Fire native event if possible so blur/focus sequence is correct
+			trigger: function() {
+				if ( this !== document.activeElement && this.focus ) {
+					try {
+						this.focus();
+						return false;
+					} catch ( e ) {
+						// Support: IE<9
+						// If we error on focus to hidden element (#1486, #12518),
+						// let .trigger() run the handlers
+					}
+				}
+			},
+			delegateType: "focusin"
+		},
+		blur: {
+			trigger: function() {
+				if ( this === document.activeElement && this.blur ) {
+					this.blur();
+					return false;
+				}
+			},
+			delegateType: "focusout"
+		},
+
+		beforeunload: {
+			postDispatch: function( event ) {
+
+				// Even when returnValue equals to undefined Firefox will still show alert
+				if ( event.result !== undefined ) {
+					event.originalEvent.returnValue = event.result;
+				}
+			}
+		}
+	},
+
+	simulate: function( type, elem, event, bubble ) {
+		// Piggyback on a donor event to simulate a different one.
+		// Fake originalEvent to avoid donor's stopPropagation, but if the
+		// simulated event prevents default then we do the same on the donor.
+		var e = jQuery.extend(
+			new jQuery.Event(),
+			event,
+			{ type: type,
+				isSimulated: true,
+				originalEvent: {}
+			}
+		);
+		if ( bubble ) {
+			jQuery.event.trigger( e, null, elem );
+		} else {
+			jQuery.event.dispatch.call( elem, e );
+		}
+		if ( e.isDefaultPrevented() ) {
+			event.preventDefault();
+		}
+	}
+};
+
+jQuery.removeEvent = document.removeEventListener ?
+	function( elem, type, handle ) {
+		if ( elem.removeEventListener ) {
+			elem.removeEventListener( type, handle, false );
+		}
+	} :
+	function( elem, type, handle ) {
+		var name = "on" + type;
+
+		if ( elem.detachEvent ) {
+
+			// #8545, #7054, preventing memory leaks for custom events in IE6-8
+			// detachEvent needed property on element, by name of that event, to properly expose it to GC
+			if ( typeof elem[ name ] === core_strundefined ) {
+				elem[ name ] = null;
+			}
+
+			elem.detachEvent( name, handle );
+		}
+	};
+
+jQuery.Event = function( src, props ) {
+	// Allow instantiation without the 'new' keyword
+	if ( !(this instanceof jQuery.Event) ) {
+		return new jQuery.Event( src, props );
+	}
+
+	// Event object
+	if ( src && src.type ) {
+		this.originalEvent = src;
+		this.type = src.type;
+
+		// Events bubbling up the document may have been marked as prevented
+		// by a handler lower down the tree; reflect the correct value.
+		this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
+			src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
+
+	// Event type
+	} else {
+		this.type = src;
+	}
+
+	// Put explicitly provided properties onto the event object
+	if ( props ) {
+		jQuery.extend( this, props );
+	}
+
+	// Create a timestamp if incoming event doesn't have one
+	this.timeStamp = src && src.timeStamp || jQuery.now();
+
+	// Mark it as fixed
+	this[ jQuery.expando ] = true;
+};
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+	isDefaultPrevented: returnFalse,
+	isPropagationStopped: returnFalse,
+	isImmediatePropagationStopped: returnFalse,
+
+	preventDefault: function() {
+		var e = this.originalEvent;
+
+		this.isDefaultPrevented = returnTrue;
+		if ( !e ) {
+			return;
+		}
+
+		// If preventDefault exists, run it on the original event
+		if ( e.preventDefault ) {
+			e.preventDefault();
+
+		// Support: IE
+		// Otherwise set the returnValue property of the original event to false
+		} else {
+			e.returnValue = false;
+		}
+	},
+	stopPropagation: function() {
+		var e = this.originalEvent;
+
+		this.isPropagationStopped = returnTrue;
+		if ( !e ) {
+			return;
+		}
+		// If stopPropagation exists, run it on the original event
+		if ( e.stopPropagation ) {
+			e.stopPropagation();
+		}
+
+		// Support: IE
+		// Set the cancelBubble property of the original event to true
+		e.cancelBubble = true;
+	},
+	stopImmediatePropagation: function() {
+		this.isImmediatePropagationStopped = returnTrue;
+		this.stopPropagation();
+	}
+};
+
+// Create mouseenter/leave events using mouseover/out and event-time checks
+jQuery.each({
+	mouseenter: "mouseover",
+	mouseleave: "mouseout"
+}, function( orig, fix ) {
+	jQuery.event.special[ orig ] = {
+		delegateType: fix,
+		bindType: fix,
+
+		handle: function( event ) {
+			var ret,
+				target = this,
+				related = event.relatedTarget,
+				handleObj = event.handleObj;
+
+			// For mousenter/leave call the handler if related is outside the target.
+			// NB: No relatedTarget if the mouse left/entered the browser window
+			if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
+				event.type = handleObj.origType;
+				ret = handleObj.handler.apply( this, arguments );
+				event.type = fix;
+			}
+			return ret;
+		}
+	};
+});
+
+// IE submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+	jQuery.event.special.submit = {
+		setup: function() {
+			// Only need this for delegated form submit events
+			if ( jQuery.nodeName( this, "form" ) ) {
+				return false;
+			}
+
+			// Lazy-add a submit handler when a descendant form may potentially be submitted
+			jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
+				// Node name check avoids a VML-related crash in IE (#9807)
+				var elem = e.target,
+					form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
+				if ( form && !jQuery._data( form, "submitBubbles" ) ) {
+					jQuery.event.add( form, "submit._submit", function( event ) {
+						event._submit_bubble = true;
+					});
+					jQuery._data( form, "submitBubbles", true );
+				}
+			});
+			// return undefined since we don't need an event listener
+		},
+
+		postDispatch: function( event ) {
+			// If form was submitted by the user, bubble the event up the tree
+			if ( event._submit_bubble ) {
+				delete event._submit_bubble;
+				if ( this.parentNode && !event.isTrigger ) {
+					jQuery.event.simulate( "submit", this.parentNode, event, true );
+				}
+			}
+		},
+
+		teardown: function() {
+			// Only need this for delegated form submit events
+			if ( jQuery.nodeName( this, "form" ) ) {
+				return false;
+			}
+
+			// Remove delegated handlers; cleanData eventually reaps submit handlers attached above
+			jQuery.event.remove( this, "._submit" );
+		}
+	};
+}
+
+// IE change delegation and checkbox/radio fix
+if ( !jQuery.support.changeBubbles ) {
+
+	jQuery.event.special.change = {
+
+		setup: function() {
+
+			if ( rformElems.test( this.nodeName ) ) {
+				// IE doesn't fire change on a check/radio until blur; trigger it on click
+				// after a propertychange. Eat the blur-change in special.change.handle.
+				// This still fires onchange a second time for check/radio after blur.
+				if ( this.type === "checkbox" || this.type === "radio" ) {
+					jQuery.event.add( this, "propertychange._change", function( event ) {
+						if ( event.originalEvent.propertyName === "checked" ) {
+							this._just_changed = true;
+						}
+					});
+					jQuery.event.add( this, "click._change", function( event ) {
+						if ( this._just_changed && !event.isTrigger ) {
+							this._just_changed = false;
+						}
+						// Allow triggered, simulated change events (#11500)
+						jQuery.event.simulate( "change", this, event, true );
+					});
+				}
+				return false;
+			}
+			// Delegated event; lazy-add a change handler on descendant inputs
+			jQuery.event.add( this, "beforeactivate._change", function( e ) {
+				var elem = e.target;
+
+				if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) {
+					jQuery.event.add( elem, "change._change", function( event ) {
+						if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
+							jQuery.event.simulate( "change", this.parentNode, event, true );
+						}
+					});
+					jQuery._data( elem, "changeBubbles", true );
+				}
+			});
+		},
+
+		handle: function( event ) {
+			var elem = event.target;
+
+			// Swallow native change events from checkbox/radio, we already triggered them above
+			if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
+				return event.handleObj.handler.apply( this, arguments );
+			}
+		},
+
+		teardown: function() {
+			jQuery.event.remove( this, "._change" );
+
+			return !rformElems.test( this.nodeName );
+		}
+	};
+}
+
+// Create "bubbling" focus and blur events
+if ( !jQuery.support.focusinBubbles ) {
+	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+		// Attach a single capturing handler while someone wants focusin/focusout
+		var attaches = 0,
+			handler = function( event ) {
+				jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
+			};
+
+		jQuery.event.special[ fix ] = {
+			setup: function() {
+				if ( attaches++ === 0 ) {
+					document.addEventListener( orig, handler, true );
+				}
+			},
+			teardown: function() {
+				if ( --attaches === 0 ) {
+					document.removeEventListener( orig, handler, true );
+				}
+			}
+		};
+	});
+}
+
+jQuery.fn.extend({
+
+	on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
+		var type, origFn;
+
+		// Types can be a map of types/handlers
+		if ( typeof types === "object" ) {
+			// ( types-Object, selector, data )
+			if ( typeof selector !== "string" ) {
+				// ( types-Object, data )
+				data = data || selector;
+				selector = undefined;
+			}
+			for ( type in types ) {
+				this.on( type, selector, data, types[ type ], one );
+			}
+			return this;
+		}
+
+		if ( data == null && fn == null ) {
+			// ( types, fn )
+			fn = selector;
+			data = selector = undefined;
+		} else if ( fn == null ) {
+			if ( typeof selector === "string" ) {
+				// ( types, selector, fn )
+				fn = data;
+				data = undefined;
+			} else {
+				// ( types, data, fn )
+				fn = data;
+				data = selector;
+				selector = undefined;
+			}
+		}
+		if ( fn === false ) {
+			fn = returnFalse;
+		} else if ( !fn ) {
+			return this;
+		}
+
+		if ( one === 1 ) {
+			origFn = fn;
+			fn = function( event ) {
+				// Can use an empty set, since event contains the info
+				jQuery().off( event );
+				return origFn.apply( this, arguments );
+			};
+			// Use same guid so caller can remove using origFn
+			fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+		}
+		return this.each( function() {
+			jQuery.event.add( this, types, fn, data, selector );
+		});
+	},
+	one: function( types, selector, data, fn ) {
+		return this.on( types, selector, data, fn, 1 );
+	},
+	off: function( types, selector, fn ) {
+		var handleObj, type;
+		if ( types && types.preventDefault && types.handleObj ) {
+			// ( event )  dispatched jQuery.Event
+			handleObj = types.handleObj;
+			jQuery( types.delegateTarget ).off(
+				handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
+				handleObj.selector,
+				handleObj.handler
+			);
+			return this;
+		}
+		if ( typeof types === "object" ) {
+			// ( types-object [, selector] )
+			for ( type in types ) {
+				this.off( type, selector, types[ type ] );
+			}
+			return this;
+		}
+		if ( selector === false || typeof selector === "function" ) {
+			// ( types [, fn] )
+			fn = selector;
+			selector = undefined;
+		}
+		if ( fn === false ) {
+			fn = returnFalse;
+		}
+		return this.each(function() {
+			jQuery.event.remove( this, types, fn, selector );
+		});
+	},
+
+	bind: function( types, data, fn ) {
+		return this.on( types, null, data, fn );
+	},
+	unbind: function( types, fn ) {
+		return this.off( types, null, fn );
+	},
+
+	delegate: function( selector, types, data, fn ) {
+		return this.on( types, selector, data, fn );
+	},
+	undelegate: function( selector, types, fn ) {
+		// ( namespace ) or ( selector, types [, fn] )
+		return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
+	},
+
+	trigger: function( type, data ) {
+		return this.each(function() {
+			jQuery.event.trigger( type, data, this );
+		});
+	},
+	triggerHandler: function( type, data ) {
+		var elem = this[0];
+		if ( elem ) {
+			return jQuery.event.trigger( type, data, elem, true );
+		}
+	}
+});
+/*!
+ * Sizzle CSS Selector Engine
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://sizzlejs.com/
+ */
+(function( window, undefined ) {
+
+var i,
+	cachedruns,
+	Expr,
+	getText,
+	isXML,
+	compile,
+	hasDuplicate,
+	outermostContext,
+
+	// Local document vars
+	setDocument,
+	document,
+	docElem,
+	documentIsXML,
+	rbuggyQSA,
+	rbuggyMatches,
+	matches,
+	contains,
+	sortOrder,
+
+	// Instance-specific data
+	expando = "sizzle" + -(new Date()),
+	preferredDoc = window.document,
+	support = {},
+	dirruns = 0,
+	done = 0,
+	classCache = createCache(),
+	tokenCache = createCache(),
+	compilerCache = createCache(),
+
+	// General-purpose constants
+	strundefined = typeof undefined,
+	MAX_NEGATIVE = 1 << 31,
+
+	// Array methods
+	arr = [],
+	pop = arr.pop,
+	push = arr.push,
+	slice = arr.slice,
+	// Use a stripped-down indexOf if we can't use a native one
+	indexOf = arr.indexOf || function( elem ) {
+		var i = 0,
+			len = this.length;
+		for ( ; i < len; i++ ) {
+			if ( this[i] === elem ) {
+				return i;
+			}
+		}
+		return -1;
+	},
+
+
+	// Regular expressions
+
+	// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
+	whitespace = "[\\x20\\t\\r\\n\\f]",
+	// http://www.w3.org/TR/css3-syntax/#characters
+	characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
+
+	// Loosely modeled on CSS identifier characters
+	// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
+	// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+	identifier = characterEncoding.replace( "w", "w#" ),
+
+	// Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
+	operators = "([*^$|!~]?=)",
+	attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
+		"*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
+
+	// Prefer arguments quoted,
+	//   then not containing pseudos/brackets,
+	//   then attribute selectors/non-parenthetical expressions,
+	//   then anything else
+	// These preferences are here to reduce the number of selectors
+	//   needing tokenize in the PSEUDO preFilter
+	pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
+
+	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+	rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ),
+	rpseudo = new RegExp( pseudos ),
+	ridentifier = new RegExp( "^" + identifier + "$" ),
+
+	matchExpr = {
+		"ID": new RegExp( "^#(" + characterEncoding + ")" ),
+		"CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
+		"NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),
+		"TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
+		"ATTR": new RegExp( "^" + attributes ),
+		"PSEUDO": new RegExp( "^" + pseudos ),
+		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+		// For use in libraries implementing .is()
+		// We use this for POS matching in `select`
+		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+	},
+
+	rsibling = /[\x20\t\r\n\f]*[+~]/,
+
+	rnative = /^[^{]+\{\s*\[native code/,
+
+	// Easily-parseable/retrievable ID or TAG or CLASS selectors
+	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+	rinputs = /^(?:input|select|textarea|button)$/i,
+	rheader = /^h\d$/i,
+
+	rescape = /'|\\/g,
+	rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,
+
+	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+	runescape = /\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,
+	funescape = function( _, escaped ) {
+		var high = "0x" + escaped - 0x10000;
+		// NaN means non-codepoint
+		return high !== high ?
+			escaped :
+			// BMP codepoint
+			high < 0 ?
+				String.fromCharCode( high + 0x10000 ) :
+				// Supplemental Plane codepoint (surrogate pair)
+				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+	};
+
+// Use a stripped-down slice if we can't use a native one
+try {
+	slice.call( preferredDoc.documentElement.childNodes, 0 )[0].nodeType;
+} catch ( e ) {
+	slice = function( i ) {
+		var elem,
+			results = [];
+		while ( (elem = this[i++]) ) {
+			results.push( elem );
+		}
+		return results;
+	};
+}
+
+/**
+ * For feature detection
+ * @param {Function} fn The function to test for native support
+ */
+function isNative( fn ) {
+	return rnative.test( fn + "" );
+}
+
+/**
+ * Create key-value caches of limited size
+ * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
+ *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ *	deleting the oldest entry
+ */
+function createCache() {
+	var cache,
+		keys = [];
+
+	return (cache = function( key, value ) {
+		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+		if ( keys.push( key += " " ) > Expr.cacheLength ) {
+			// Only keep the most recent entries
+			delete cache[ keys.shift() ];
+		}
+		return (cache[ key ] = value);
+	});
+}
+
+/**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+	fn[ expando ] = true;
+	return fn;
+}
+
+/**
+ * Support testing using an element
+ * @param {Function} fn Passed the created div and expects a boolean result
+ */
+function assert( fn ) {
+	var div = document.createElement("div");
+
+	try {
+		return fn( div );
+	} catch (e) {
+		return false;
+	} finally {
+		// release memory in IE
+		div = null;
+	}
+}
+
+function Sizzle( selector, context, results, seed ) {
+	var match, elem, m, nodeType,
+		// QSA vars
+		i, groups, old, nid, newContext, newSelector;
+
+	if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+		setDocument( context );
+	}
+
+	context = context || document;
+	results = results || [];
+
+	if ( !selector || typeof selector !== "string" ) {
+		return results;
+	}
+
+	if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
+		return [];
+	}
+
+	if ( !documentIsXML && !seed ) {
+
+		// Shortcuts
+		if ( (match = rquickExpr.exec( selector )) ) {
+			// Speed-up: Sizzle("#ID")
+			if ( (m = match[1]) ) {
+				if ( nodeType === 9 ) {
+					elem = context.getElementById( m );
+					// Check parentNode to catch when Blackberry 4.6 returns
+					// nodes that are no longer in the document #6963
+					if ( elem && elem.parentNode ) {
+						// Handle the case where IE, Opera, and Webkit return items
+						// by name instead of ID
+						if ( elem.id === m ) {
+							results.push( elem );
+							return results;
+						}
+					} else {
+						return results;
+					}
+				} else {
+					// Context is not a document
+					if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
+						contains( context, elem ) && elem.id === m ) {
+						results.push( elem );
+						return results;
+					}
+				}
+
+			// Speed-up: Sizzle("TAG")
+			} else if ( match[2] ) {
+				push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
+				return results;
+
+			// Speed-up: Sizzle(".CLASS")
+			} else if ( (m = match[3]) && support.getByClassName && context.getElementsByClassName ) {
+				push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
+				return results;
+			}
+		}
+
+		// QSA path
+		if ( support.qsa && !rbuggyQSA.test(selector) ) {
+			old = true;
+			nid = expando;
+			newContext = context;
+			newSelector = nodeType === 9 && selector;
+
+			// qSA works strangely on Element-rooted queries
+			// We can work around this by specifying an extra ID on the root
+			// and working up from there (Thanks to Andrew Dupont for the technique)
+			// IE 8 doesn't work on object elements
+			if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+				groups = tokenize( selector );
+
+				if ( (old = context.getAttribute("id")) ) {
+					nid = old.replace( rescape, "\\$&" );
+				} else {
+					context.setAttribute( "id", nid );
+				}
+				nid = "[id='" + nid + "'] ";
+
+				i = groups.length;
+				while ( i-- ) {
+					groups[i] = nid + toSelector( groups[i] );
+				}
+				newContext = rsibling.test( selector ) && context.parentNode || context;
+				newSelector = groups.join(",");
+			}
+
+			if ( newSelector ) {
+				try {
+					push.apply( results, slice.call( newContext.querySelectorAll(
+						newSelector
+					), 0 ) );
+					return results;
+				} catch(qsaError) {
+				} finally {
+					if ( !old ) {
+						context.removeAttribute("id");
+					}
+				}
+			}
+		}
+	}
+
+	// All others
+	return select( selector.replace( rtrim, "$1" ), context, results, seed );
+}
+
+/**
+ * Detect xml
+ * @param {Element|Object} elem An element or a document
+ */
+isXML = Sizzle.isXML = function( elem ) {
+	// documentElement is verified for cases where it doesn't yet exist
+	// (such as loading iframes in IE - #4833)
+	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+	return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+setDocument = Sizzle.setDocument = function( node ) {
+	var doc = node ? node.ownerDocument || node : preferredDoc;
+
+	// If no document and documentElement is available, return
+	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+		return document;
+	}
+
+	// Set our document
+	document = doc;
+	docElem = doc.documentElement;
+
+	// Support tests
+	documentIsXML = isXML( doc );
+
+	// Check if getElementsByTagName("*") returns only elements
+	support.tagNameNoComments = assert(function( div ) {
+		div.appendChild( doc.createComment("") );
+		return !div.getElementsByTagName("*").length;
+	});
+
+	// Check if attributes should be retrieved by attribute nodes
+	support.attributes = assert(function( div ) {
+		div.innerHTML = "<select></select>";
+		var type = typeof div.lastChild.getAttribute("multiple");
+		// IE8 returns a string for some attributes even when not present
+		return type !== "boolean" && type !== "string";
+	});
+
+	// Check if getElementsByClassName can be trusted
+	support.getByClassName = assert(function( div ) {
+		// Opera can't find a second classname (in 9.6)
+		div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
+		if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) {
+			return false;
+		}
+
+		// Safari 3.2 caches class attributes and doesn't catch changes
+		div.lastChild.className = "e";
+		return div.getElementsByClassName("e").length === 2;
+	});
+
+	// Check if getElementById returns elements by name
+	// Check if getElementsByName privileges form controls or returns elements by ID
+	support.getByName = assert(function( div ) {
+		// Inject content
+		div.id = expando + 0;
+		div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
+		docElem.insertBefore( div, docElem.firstChild );
+
+		// Test
+		var pass = doc.getElementsByName &&
+			// buggy browsers will return fewer than the correct 2
+			doc.getElementsByName( expando ).length === 2 +
+			// buggy browsers will return more than the correct 0
+			doc.getElementsByName( expando + 0 ).length;
+		support.getIdNotName = !doc.getElementById( expando );
+
+		// Cleanup
+		docElem.removeChild( div );
+
+		return pass;
+	});
+
+	// IE6/7 return modified attributes
+	Expr.attrHandle = assert(function( div ) {
+		div.innerHTML = "<a href='#'></a>";
+		return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
+			div.firstChild.getAttribute("href") === "#";
+	}) ?
+		{} :
+		{
+			"href": function( elem ) {
+				return elem.getAttribute( "href", 2 );
+			},
+			"type": function( elem ) {
+				return elem.getAttribute("type");
+			}
+		};
+
+	// ID find and filter
+	if ( support.getIdNotName ) {
+		Expr.find["ID"] = function( id, context ) {
+			if ( typeof context.getElementById !== strundefined && !documentIsXML ) {
+				var m = context.getElementById( id );
+				// Check parentNode to catch when Blackberry 4.6 returns
+				// nodes that are no longer in the document #6963
+				return m && m.parentNode ? [m] : [];
+			}
+		};
+		Expr.filter["ID"] = function( id ) {
+			var attrId = id.replace( runescape, funescape );
+			return function( elem ) {
+				return elem.getAttribute("id") === attrId;
+			};
+		};
+	} else {
+		Expr.find["ID"] = function( id, context ) {
+			if ( typeof context.getElementById !== strundefined && !documentIsXML ) {
+				var m = context.getElementById( id );
+
+				return m ?
+					m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ?
+						[m] :
+						undefined :
+					[];
+			}
+		};
+		Expr.filter["ID"] =  function( id ) {
+			var attrId = id.replace( runescape, funescape );
+			return function( elem ) {
+				var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
+				return node && node.value === attrId;
+			};
+		};
+	}
+
+	// Tag
+	Expr.find["TAG"] = support.tagNameNoComments ?
+		function( tag, context ) {
+			if ( typeof context.getElementsByTagName !== strundefined ) {
+				return context.getElementsByTagName( tag );
+			}
+		} :
+		function( tag, context ) {
+			var elem,
+				tmp = [],
+				i = 0,
+				results = context.getElementsByTagName( tag );
+
+			// Filter out possible comments
+			if ( tag === "*" ) {
+				while ( (elem = results[i++]) ) {
+					if ( elem.nodeType === 1 ) {
+						tmp.push( elem );
+					}
+				}
+
+				return tmp;
+			}
+			return results;
+		};
+
+	// Name
+	Expr.find["NAME"] = support.getByName && function( tag, context ) {
+		if ( typeof context.getElementsByName !== strundefined ) {
+			return context.getElementsByName( name );
+		}
+	};
+
+	// Class
+	Expr.find["CLASS"] = support.getByClassName && function( className, context ) {
+		if ( typeof context.getElementsByClassName !== strundefined && !documentIsXML ) {
+			return context.getElementsByClassName( className );
+		}
+	};
+
+	// QSA and matchesSelector support
+
+	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+	rbuggyMatches = [];
+
+	// qSa(:focus) reports false when true (Chrome 21),
+	// no need to also add to buggyMatches since matches checks buggyQSA
+	// A support test would require too much code (would include document ready)
+	rbuggyQSA = [ ":focus" ];
+
+	if ( (support.qsa = isNative(doc.querySelectorAll)) ) {
+		// Build QSA regex
+		// Regex strategy adopted from Diego Perini
+		assert(function( div ) {
+			// Select is set to empty string on purpose
+			// This is to test IE's treatment of not explictly
+			// setting a boolean content attribute,
+			// since its presence should be enough
+			// http://bugs.jquery.com/ticket/12359
+			div.innerHTML = "<select><option selected=''></option></select>";
+
+			// IE8 - Some boolean attributes are not treated correctly
+			if ( !div.querySelectorAll("[selected]").length ) {
+				rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" );
+			}
+
+			// Webkit/Opera - :checked should return selected option elements
+			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+			// IE8 throws error here and will not see later tests
+			if ( !div.querySelectorAll(":checked").length ) {
+				rbuggyQSA.push(":checked");
+			}
+		});
+
+		assert(function( div ) {
+
+			// Opera 10-12/IE8 - ^= $= *= and empty values
+			// Should not select anything
+			div.innerHTML = "<input type='hidden' i=''/>";
+			if ( div.querySelectorAll("[i^='']").length ) {
+				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );
+			}
+
+			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+			// IE8 throws error here and will not see later tests
+			if ( !div.querySelectorAll(":enabled").length ) {
+				rbuggyQSA.push( ":enabled", ":disabled" );
+			}
+
+			// Opera 10-11 does not throw on post-comma invalid pseudos
+			div.querySelectorAll("*,:x");
+			rbuggyQSA.push(",.*:");
+		});
+	}
+
+	if ( (support.matchesSelector = isNative( (matches = docElem.matchesSelector ||
+		docElem.mozMatchesSelector ||
+		docElem.webkitMatchesSelector ||
+		docElem.oMatchesSelector ||
+		docElem.msMatchesSelector) )) ) {
+
+		assert(function( div ) {
+			// Check to see if it's possible to do matchesSelector
+			// on a disconnected node (IE 9)
+			support.disconnectedMatch = matches.call( div, "div" );
+
+			// This should fail with an exception
+			// Gecko does not error, returns false instead
+			matches.call( div, "[s!='']:x" );
+			rbuggyMatches.push( "!=", pseudos );
+		});
+	}
+
+	rbuggyQSA = new RegExp( rbuggyQSA.join("|") );
+	rbuggyMatches = new RegExp( rbuggyMatches.join("|") );
+
+	// Element contains another
+	// Purposefully does not implement inclusive descendent
+	// As in, an element does not contain itself
+	contains = isNative(docElem.contains) || docElem.compareDocumentPosition ?
+		function( a, b ) {
+			var adown = a.nodeType === 9 ? a.documentElement : a,
+				bup = b && b.parentNode;
+			return a === bup || !!( bup && bup.nodeType === 1 && (
+				adown.contains ?
+					adown.contains( bup ) :
+					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+			));
+		} :
+		function( a, b ) {
+			if ( b ) {
+				while ( (b = b.parentNode) ) {
+					if ( b === a ) {
+						return true;
+					}
+				}
+			}
+			return false;
+		};
+
+	// Document order sorting
+	sortOrder = docElem.compareDocumentPosition ?
+	function( a, b ) {
+		var compare;
+
+		if ( a === b ) {
+			hasDuplicate = true;
+			return 0;
+		}
+
+		if ( (compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b )) ) {
+			if ( compare & 1 || a.parentNode && a.parentNode.nodeType === 11 ) {
+				if ( a === doc || contains( preferredDoc, a ) ) {
+					return -1;
+				}
+				if ( b === doc || contains( preferredDoc, b ) ) {
+					return 1;
+				}
+				return 0;
+			}
+			return compare & 4 ? -1 : 1;
+		}
+
+		return a.compareDocumentPosition ? -1 : 1;
+	} :
+	function( a, b ) {
+		var cur,
+			i = 0,
+			aup = a.parentNode,
+			bup = b.parentNode,
+			ap = [ a ],
+			bp = [ b ];
+
+		// Exit early if the nodes are identical
+		if ( a === b ) {
+			hasDuplicate = true;
+			return 0;
+
+		// Parentless nodes are either documents or disconnected
+		} else if ( !aup || !bup ) {
+			return a === doc ? -1 :
+				b === doc ? 1 :
+				aup ? -1 :
+				bup ? 1 :
+				0;
+
+		// If the nodes are siblings, we can do a quick check
+		} else if ( aup === bup ) {
+			return siblingCheck( a, b );
+		}
+
+		// Otherwise we need full lists of their ancestors for comparison
+		cur = a;
+		while ( (cur = cur.parentNode) ) {
+			ap.unshift( cur );
+		}
+		cur = b;
+		while ( (cur = cur.parentNode) ) {
+			bp.unshift( cur );
+		}
+
+		// Walk down the tree looking for a discrepancy
+		while ( ap[i] === bp[i] ) {
+			i++;
+		}
+
+		return i ?
+			// Do a sibling check if the nodes have a common ancestor
+			siblingCheck( ap[i], bp[i] ) :
+
+			// Otherwise nodes in our document sort first
+			ap[i] === preferredDoc ? -1 :
+			bp[i] === preferredDoc ? 1 :
+			0;
+	};
+
+	// Always assume the presence of duplicates if sort doesn't
+	// pass them to our comparison function (as in Google Chrome).
+	hasDuplicate = false;
+	[0, 0].sort( sortOrder );
+	support.detectDuplicates = hasDuplicate;
+
+	return document;
+};
+
+Sizzle.matches = function( expr, elements ) {
+	return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+	// Set document vars if needed
+	if ( ( elem.ownerDocument || elem ) !== document ) {
+		setDocument( elem );
+	}
+
+	// Make sure that attribute selectors are quoted
+	expr = expr.replace( rattributeQuotes, "='$1']" );
+
+	// rbuggyQSA always contains :focus, so no need for an existence check
+	if ( support.matchesSelector && !documentIsXML && (!rbuggyMatches || !rbuggyMatches.test(expr)) && !rbuggyQSA.test(expr) ) {
+		try {
+			var ret = matches.call( elem, expr );
+
+			// IE 9's matchesSelector returns false on disconnected nodes
+			if ( ret || support.disconnectedMatch ||
+					// As well, disconnected nodes are said to be in a document
+					// fragment in IE 9
+					elem.document && elem.document.nodeType !== 11 ) {
+				return ret;
+			}
+		} catch(e) {}
+	}
+
+	return Sizzle( expr, document, null, [elem] ).length > 0;
+};
+
+Sizzle.contains = function( context, elem ) {
+	// Set document vars if needed
+	if ( ( context.ownerDocument || context ) !== document ) {
+		setDocument( context );
+	}
+	return contains( context, elem );
+};
+
+Sizzle.attr = function( elem, name ) {
+	var val;
+
+	// Set document vars if needed
+	if ( ( elem.ownerDocument || elem ) !== document ) {
+		setDocument( elem );
+	}
+
+	if ( !documentIsXML ) {
+		name = name.toLowerCase();
+	}
+	if ( (val = Expr.attrHandle[ name ]) ) {
+		return val( elem );
+	}
+	if ( documentIsXML || support.attributes ) {
+		return elem.getAttribute( name );
+	}
+	return ( (val = elem.getAttributeNode( name )) || elem.getAttribute( name ) ) && elem[ name ] === true ?
+		name :
+		val && val.specified ? val.value : null;
+};
+
+Sizzle.error = function( msg ) {
+	throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+// Document sorting and removing duplicates
+Sizzle.uniqueSort = function( results ) {
+	var elem,
+		duplicates = [],
+		i = 1,
+		j = 0;
+
+	// Unless we *know* we can detect duplicates, assume their presence
+	hasDuplicate = !support.detectDuplicates;
+	results.sort( sortOrder );
+
+	if ( hasDuplicate ) {
+		for ( ; (elem = results[i]); i++ ) {
+			if ( elem === results[ i - 1 ] ) {
+				j = duplicates.push( i );
+			}
+		}
+		while ( j-- ) {
+			results.splice( duplicates[ j ], 1 );
+		}
+	}
+
+	return results;
+};
+
+function siblingCheck( a, b ) {
+	var cur = b && a,
+		diff = cur && ( ~b.sourceIndex || MAX_NEGATIVE ) - ( ~a.sourceIndex || MAX_NEGATIVE );
+
+	// Use IE sourceIndex if available on both nodes
+	if ( diff ) {
+		return diff;
+	}
+
+	// Check if b follows a
+	if ( cur ) {
+		while ( (cur = cur.nextSibling) ) {
+			if ( cur === b ) {
+				return -1;
+			}
+		}
+	}
+
+	return a ? 1 : -1;
+}
+
+// Returns a function to use in pseudos for input types
+function createInputPseudo( type ) {
+	return function( elem ) {
+		var name = elem.nodeName.toLowerCase();
+		return name === "input" && elem.type === type;
+	};
+}
+
+// Returns a function to use in pseudos for buttons
+function createButtonPseudo( type ) {
+	return function( elem ) {
+		var name = elem.nodeName.toLowerCase();
+		return (name === "input" || name === "button") && elem.type === type;
+	};
+}
+
+// Returns a function to use in pseudos for positionals
+function createPositionalPseudo( fn ) {
+	return markFunction(function( argument ) {
+		argument = +argument;
+		return markFunction(function( seed, matches ) {
+			var j,
+				matchIndexes = fn( [], seed.length, argument ),
+				i = matchIndexes.length;
+
+			// Match elements found at the specified indexes
+			while ( i-- ) {
+				if ( seed[ (j = matchIndexes[i]) ] ) {
+					seed[j] = !(matches[j] = seed[j]);
+				}
+			}
+		});
+	});
+}
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+	var node,
+		ret = "",
+		i = 0,
+		nodeType = elem.nodeType;
+
+	if ( !nodeType ) {
+		// If no nodeType, this is expected to be an array
+		for ( ; (node = elem[i]); i++ ) {
+			// Do not traverse comment nodes
+			ret += getText( node );
+		}
+	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+		// Use textContent for elements
+		// innerText usage removed for consistency of new lines (see #11153)
+		if ( typeof elem.textContent === "string" ) {
+			return elem.textContent;
+		} else {
+			// Traverse its children
+			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+				ret += getText( elem );
+			}
+		}
+	} else if ( nodeType === 3 || nodeType === 4 ) {
+		return elem.nodeValue;
+	}
+	// Do not include comment or processing instruction nodes
+
+	return ret;
+};
+
+Expr = Sizzle.selectors = {
+
+	// Can be adjusted by the user
+	cacheLength: 50,
+
+	createPseudo: markFunction,
+
+	match: matchExpr,
+
+	find: {},
+
+	relative: {
+		">": { dir: "parentNode", first: true },
+		" ": { dir: "parentNode" },
+		"+": { dir: "previousSibling", first: true },
+		"~": { dir: "previousSibling" }
+	},
+
+	preFilter: {
+		"ATTR": function( match ) {
+			match[1] = match[1].replace( runescape, funescape );
+
+			// Move the given value to match[3] whether quoted or unquoted
+			match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
+
+			if ( match[2] === "~=" ) {
+				match[3] = " " + match[3] + " ";
+			}
+
+			return match.slice( 0, 4 );
+		},
+
+		"CHILD": function( match ) {
+			/* matches from matchExpr["CHILD"]
+				1 type (only|nth|...)
+				2 what (child|of-type)
+				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+				4 xn-component of xn+y argument ([+-]?\d*n|)
+				5 sign of xn-component
+				6 x of xn-component
+				7 sign of y-component
+				8 y of y-component
+			*/
+			match[1] = match[1].toLowerCase();
+
+			if ( match[1].slice( 0, 3 ) === "nth" ) {
+				// nth-* requires argument
+				if ( !match[3] ) {
+					Sizzle.error( match[0] );
+				}
+
+				// numeric x and y parameters for Expr.filter.CHILD
+				// remember that false/true cast respectively to 0/1
+				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
+				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+
+			// other types prohibit arguments
+			} else if ( match[3] ) {
+				Sizzle.error( match[0] );
+			}
+
+			return match;
+		},
+
+		"PSEUDO": function( match ) {
+			var excess,
+				unquoted = !match[5] && match[2];
+
+			if ( matchExpr["CHILD"].test( match[0] ) ) {
+				return null;
+			}
+
+			// Accept quoted arguments as-is
+			if ( match[4] ) {
+				match[2] = match[4];
+
+			// Strip excess characters from unquoted arguments
+			} else if ( unquoted && rpseudo.test( unquoted ) &&
+				// Get excess from tokenize (recursively)
+				(excess = tokenize( unquoted, true )) &&
+				// advance to the next closing parenthesis
+				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+				// excess is a negative index
+				match[0] = match[0].slice( 0, excess );
+				match[2] = unquoted.slice( 0, excess );
+			}
+
+			// Return only captures needed by the pseudo filter method (type and argument)
+			return match.slice( 0, 3 );
+		}
+	},
+
+	filter: {
+
+		"TAG": function( nodeName ) {
+			if ( nodeName === "*" ) {
+				return function() { return true; };
+			}
+
+			nodeName = nodeName.replace( runescape, funescape ).toLowerCase();
+			return function( elem ) {
+				return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+			};
+		},
+
+		"CLASS": function( className ) {
+			var pattern = classCache[ className + " " ];
+
+			return pattern ||
+				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
+				classCache( className, function( elem ) {
+					return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );
+				});
+		},
+
+		"ATTR": function( name, operator, check ) {
+			return function( elem ) {
+				var result = Sizzle.attr( elem, name );
+
+				if ( result == null ) {
+					return operator === "!=";
+				}
+				if ( !operator ) {
+					return true;
+				}
+
+				result += "";
+
+				return operator === "=" ? result === check :
+					operator === "!=" ? result !== check :
+					operator === "^=" ? check && result.indexOf( check ) === 0 :
+					operator === "*=" ? check && result.indexOf( check ) > -1 :
+					operator === "$=" ? check && result.slice( -check.length ) === check :
+					operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
+					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
+					false;
+			};
+		},
+
+		"CHILD": function( type, what, argument, first, last ) {
+			var simple = type.slice( 0, 3 ) !== "nth",
+				forward = type.slice( -4 ) !== "last",
+				ofType = what === "of-type";
+
+			return first === 1 && last === 0 ?
+
+				// Shortcut for :nth-*(n)
+				function( elem ) {
+					return !!elem.parentNode;
+				} :
+
+				function( elem, context, xml ) {
+					var cache, outerCache, node, diff, nodeIndex, start,
+						dir = simple !== forward ? "nextSibling" : "previousSibling",
+						parent = elem.parentNode,
+						name = ofType && elem.nodeName.toLowerCase(),
+						useCache = !xml && !ofType;
+
+					if ( parent ) {
+
+						// :(first|last|only)-(child|of-type)
+						if ( simple ) {
+							while ( dir ) {
+								node = elem;
+								while ( (node = node[ dir ]) ) {
+									if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
+										return false;
+									}
+								}
+								// Reverse direction for :only-* (if we haven't yet done so)
+								start = dir = type === "only" && !start && "nextSibling";
+							}
+							return true;
+						}
+
+						start = [ forward ? parent.firstChild : parent.lastChild ];
+
+						// non-xml :nth-child(...) stores cache data on `parent`
+						if ( forward && useCache ) {
+							// Seek `elem` from a previously-cached index
+							outerCache = parent[ expando ] || (parent[ expando ] = {});
+							cache = outerCache[ type ] || [];
+							nodeIndex = cache[0] === dirruns && cache[1];
+							diff = cache[0] === dirruns && cache[2];
+							node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+							while ( (node = ++nodeIndex && node && node[ dir ] ||
+
+								// Fallback to seeking `elem` from the start
+								(diff = nodeIndex = 0) || start.pop()) ) {
+
+								// When found, cache indexes on `parent` and break
+								if ( node.nodeType === 1 && ++diff && node === elem ) {
+									outerCache[ type ] = [ dirruns, nodeIndex, diff ];
+									break;
+								}
+							}
+
+						// Use previously-cached element index if available
+						} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
+							diff = cache[1];
+
+						// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
+						} else {
+							// Use the same loop as above to seek `elem` from the start
+							while ( (node = ++nodeIndex && node && node[ dir ] ||
+								(diff = nodeIndex = 0) || start.pop()) ) {
+
+								if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
+									// Cache the index of each encountered element
+									if ( useCache ) {
+										(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
+									}
+
+									if ( node === elem ) {
+										break;
+									}
+								}
+							}
+						}
+
+						// Incorporate the offset, then check against cycle size
+						diff -= last;
+						return diff === first || ( diff % first === 0 && diff / first >= 0 );
+					}
+				};
+		},
+
+		"PSEUDO": function( pseudo, argument ) {
+			// pseudo-class names are case-insensitive
+			// http://www.w3.org/TR/selectors/#pseudo-classes
+			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+			// Remember that setFilters inherits from pseudos
+			var args,
+				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+					Sizzle.error( "unsupported pseudo: " + pseudo );
+
+			// The user may use createPseudo to indicate that
+			// arguments are needed to create the filter function
+			// just as Sizzle does
+			if ( fn[ expando ] ) {
+				return fn( argument );
+			}
+
+			// But maintain support for old signatures
+			if ( fn.length > 1 ) {
+				args = [ pseudo, pseudo, "", argument ];
+				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+					markFunction(function( seed, matches ) {
+						var idx,
+							matched = fn( seed, argument ),
+							i = matched.length;
+						while ( i-- ) {
+							idx = indexOf.call( seed, matched[i] );
+							seed[ idx ] = !( matches[ idx ] = matched[i] );
+						}
+					}) :
+					function( elem ) {
+						return fn( elem, 0, args );
+					};
+			}
+
+			return fn;
+		}
+	},
+
+	pseudos: {
+		// Potentially complex pseudos
+		"not": markFunction(function( selector ) {
+			// Trim the selector passed to compile
+			// to avoid treating leading and trailing
+			// spaces as combinators
+			var input = [],
+				results = [],
+				matcher = compile( selector.replace( rtrim, "$1" ) );
+
+			return matcher[ expando ] ?
+				markFunction(function( seed, matches, context, xml ) {
+					var elem,
+						unmatched = matcher( seed, null, xml, [] ),
+						i = seed.length;
+
+					// Match elements unmatched by `matcher`
+					while ( i-- ) {
+						if ( (elem = unmatched[i]) ) {
+							seed[i] = !(matches[i] = elem);
+						}
+					}
+				}) :
+				function( elem, context, xml ) {
+					input[0] = elem;
+					matcher( input, null, xml, results );
+					return !results.pop();
+				};
+		}),
+
+		"has": markFunction(function( selector ) {
+			return function( elem ) {
+				return Sizzle( selector, elem ).length > 0;
+			};
+		}),
+
+		"contains": markFunction(function( text ) {
+			return function( elem ) {
+				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+			};
+		}),
+
+		// "Whether an element is represented by a :lang() selector
+		// is based solely on the element's language value
+		// being equal to the identifier C,
+		// or beginning with the identifier C immediately followed by "-".
+		// The matching of C against the element's language value is performed case-insensitively.
+		// The identifier C does not have to be a valid language name."
+		// http://www.w3.org/TR/selectors/#lang-pseudo
+		"lang": markFunction( function( lang ) {
+			// lang value must be a valid identifider
+			if ( !ridentifier.test(lang || "") ) {
+				Sizzle.error( "unsupported lang: " + lang );
+			}
+			lang = lang.replace( runescape, funescape ).toLowerCase();
+			return function( elem ) {
+				var elemLang;
+				do {
+					if ( (elemLang = documentIsXML ?
+						elem.getAttribute("xml:lang") || elem.getAttribute("lang") :
+						elem.lang) ) {
+
+						elemLang = elemLang.toLowerCase();
+						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
+					}
+				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+				return false;
+			};
+		}),
+
+		// Miscellaneous
+		"target": function( elem ) {
+			var hash = window.location && window.location.hash;
+			return hash && hash.slice( 1 ) === elem.id;
+		},
+
+		"root": function( elem ) {
+			return elem === docElem;
+		},
+
+		"focus": function( elem ) {
+			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+		},
+
+		// Boolean properties
+		"enabled": function( elem ) {
+			return elem.disabled === false;
+		},
+
+		"disabled": function( elem ) {
+			return elem.disabled === true;
+		},
+
+		"checked": function( elem ) {
+			// In CSS3, :checked should return both checked and selected elements
+			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+			var nodeName = elem.nodeName.toLowerCase();
+			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+		},
+
+		"selected": function( elem ) {
+			// Accessing this property makes selected-by-default
+			// options in Safari work properly
+			if ( elem.parentNode ) {
+				elem.parentNode.selectedIndex;
+			}
+
+			return elem.selected === true;
+		},
+
+		// Contents
+		"empty": function( elem ) {
+			// http://www.w3.org/TR/selectors/#empty-pseudo
+			// :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
+			//   not comment, processing instructions, or others
+			// Thanks to Diego Perini for the nodeName shortcut
+			//   Greater than "@" means alpha characters (specifically not starting with "#" or "?")
+			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+				if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) {
+					return false;
+				}
+			}
+			return true;
+		},
+
+		"parent": function( elem ) {
+			return !Expr.pseudos["empty"]( elem );
+		},
+
+		// Element/input types
+		"header": function( elem ) {
+			return rheader.test( elem.nodeName );
+		},
+
+		"input": function( elem ) {
+			return rinputs.test( elem.nodeName );
+		},
+
+		"button": function( elem ) {
+			var name = elem.nodeName.toLowerCase();
+			return name === "input" && elem.type === "button" || name === "button";
+		},
+
+		"text": function( elem ) {
+			var attr;
+			// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+			// use getAttribute instead to test this case
+			return elem.nodeName.toLowerCase() === "input" &&
+				elem.type === "text" &&
+				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type );
+		},
+
+		// Position-in-collection
+		"first": createPositionalPseudo(function() {
+			return [ 0 ];
+		}),
+
+		"last": createPositionalPseudo(function( matchIndexes, length ) {
+			return [ length - 1 ];
+		}),
+
+		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+			return [ argument < 0 ? argument + length : argument ];
+		}),
+
+		"even": createPositionalPseudo(function( matchIndexes, length ) {
+			var i = 0;
+			for ( ; i < length; i += 2 ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"odd": createPositionalPseudo(function( matchIndexes, length ) {
+			var i = 1;
+			for ( ; i < length; i += 2 ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+			var i = argument < 0 ? argument + length : argument;
+			for ( ; --i >= 0; ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+			var i = argument < 0 ? argument + length : argument;
+			for ( ; ++i < length; ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		})
+	}
+};
+
+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+	Expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+	Expr.pseudos[ i ] = createButtonPseudo( i );
+}
+
+function tokenize( selector, parseOnly ) {
+	var matched, match, tokens, type,
+		soFar, groups, preFilters,
+		cached = tokenCache[ selector + " " ];
+
+	if ( cached ) {
+		return parseOnly ? 0 : cached.slice( 0 );
+	}
+
+	soFar = selector;
+	groups = [];
+	preFilters = Expr.preFilter;
+
+	while ( soFar ) {
+
+		// Comma and first run
+		if ( !matched || (match = rcomma.exec( soFar )) ) {
+			if ( match ) {
+				// Don't consume trailing commas as valid
+				soFar = soFar.slice( match[0].length ) || soFar;
+			}
+			groups.push( tokens = [] );
+		}
+
+		matched = false;
+
+		// Combinators
+		if ( (match = rcombinators.exec( soFar )) ) {
+			matched = match.shift();
+			tokens.push( {
+				value: matched,
+				// Cast descendant combinators to space
+				type: match[0].replace( rtrim, " " )
+			} );
+			soFar = soFar.slice( matched.length );
+		}
+
+		// Filters
+		for ( type in Expr.filter ) {
+			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+				(match = preFilters[ type ]( match ))) ) {
+				matched = match.shift();
+				tokens.push( {
+					value: matched,
+					type: type,
+					matches: match
+				} );
+				soFar = soFar.slice( matched.length );
+			}
+		}
+
+		if ( !matched ) {
+			break;
+		}
+	}
+
+	// Return the length of the invalid excess
+	// if we're just parsing
+	// Otherwise, throw an error or return tokens
+	return parseOnly ?
+		soFar.length :
+		soFar ?
+			Sizzle.error( selector ) :
+			// Cache the tokens
+			tokenCache( selector, groups ).slice( 0 );
+}
+
+function toSelector( tokens ) {
+	var i = 0,
+		len = tokens.length,
+		selector = "";
+	for ( ; i < len; i++ ) {
+		selector += tokens[i].value;
+	}
+	return selector;
+}
+
+function addCombinator( matcher, combinator, base ) {
+	var dir = combinator.dir,
+		checkNonElements = base && dir === "parentNode",
+		doneName = done++;
+
+	return combinator.first ?
+		// Check against closest ancestor/preceding element
+		function( elem, context, xml ) {
+			while ( (elem = elem[ dir ]) ) {
+				if ( elem.nodeType === 1 || checkNonElements ) {
+					return matcher( elem, context, xml );
+				}
+			}
+		} :
+
+		// Check against all ancestor/preceding elements
+		function( elem, context, xml ) {
+			var data, cache, outerCache,
+				dirkey = dirruns + " " + doneName;
+
+			// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
+			if ( xml ) {
+				while ( (elem = elem[ dir ]) ) {
+					if ( elem.nodeType === 1 || checkNonElements ) {
+						if ( matcher( elem, context, xml ) ) {
+							return true;
+						}
+					}
+				}
+			} else {
+				while ( (elem = elem[ dir ]) ) {
+					if ( elem.nodeType === 1 || checkNonElements ) {
+						outerCache = elem[ expando ] || (elem[ expando ] = {});
+						if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) {
+							if ( (data = cache[1]) === true || data === cachedruns ) {
+								return data === true;
+							}
+						} else {
+							cache = outerCache[ dir ] = [ dirkey ];
+							cache[1] = matcher( elem, context, xml ) || cachedruns;
+							if ( cache[1] === true ) {
+								return true;
+							}
+						}
+					}
+				}
+			}
+		};
+}
+
+function elementMatcher( matchers ) {
+	return matchers.length > 1 ?
+		function( elem, context, xml ) {
+			var i = matchers.length;
+			while ( i-- ) {
+				if ( !matchers[i]( elem, context, xml ) ) {
+					return false;
+				}
+			}
+			return true;
+		} :
+		matchers[0];
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+	var elem,
+		newUnmatched = [],
+		i = 0,
+		len = unmatched.length,
+		mapped = map != null;
+
+	for ( ; i < len; i++ ) {
+		if ( (elem = unmatched[i]) ) {
+			if ( !filter || filter( elem, context, xml ) ) {
+				newUnmatched.push( elem );
+				if ( mapped ) {
+					map.push( i );
+				}
+			}
+		}
+	}
+
+	return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+	if ( postFilter && !postFilter[ expando ] ) {
+		postFilter = setMatcher( postFilter );
+	}
+	if ( postFinder && !postFinder[ expando ] ) {
+		postFinder = setMatcher( postFinder, postSelector );
+	}
+	return markFunction(function( seed, results, context, xml ) {
+		var temp, i, elem,
+			preMap = [],
+			postMap = [],
+			preexisting = results.length,
+
+			// Get initial elements from seed or context
+			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
+
+			// Prefilter to get matcher input, preserving a map for seed-results synchronization
+			matcherIn = preFilter && ( seed || !selector ) ?
+				condense( elems, preMap, preFilter, context, xml ) :
+				elems,
+
+			matcherOut = matcher ?
+				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+					// ...intermediate processing is necessary
+					[] :
+
+					// ...otherwise use results directly
+					results :
+				matcherIn;
+
+		// Find primary matches
+		if ( matcher ) {
+			matcher( matcherIn, matcherOut, context, xml );
+		}
+
+		// Apply postFilter
+		if ( postFilter ) {
+			temp = condense( matcherOut, postMap );
+			postFilter( temp, [], context, xml );
+
+			// Un-match failing elements by moving them back to matcherIn
+			i = temp.length;
+			while ( i-- ) {
+				if ( (elem = temp[i]) ) {
+					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+				}
+			}
+		}
+
+		if ( seed ) {
+			if ( postFinder || preFilter ) {
+				if ( postFinder ) {
+					// Get the final matcherOut by condensing this intermediate into postFinder contexts
+					temp = [];
+					i = matcherOut.length;
+					while ( i-- ) {
+						if ( (elem = matcherOut[i]) ) {
+							// Restore matcherIn since elem is not yet a final match
+							temp.push( (matcherIn[i] = elem) );
+						}
+					}
+					postFinder( null, (matcherOut = []), temp, xml );
+				}
+
+				// Move matched elements from seed to results to keep them synchronized
+				i = matcherOut.length;
+				while ( i-- ) {
+					if ( (elem = matcherOut[i]) &&
+						(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
+
+						seed[temp] = !(results[temp] = elem);
+					}
+				}
+			}
+
+		// Add elements to results, through postFinder if defined
+		} else {
+			matcherOut = condense(
+				matcherOut === results ?
+					matcherOut.splice( preexisting, matcherOut.length ) :
+					matcherOut
+			);
+			if ( postFinder ) {
+				postFinder( null, results, matcherOut, xml );
+			} else {
+				push.apply( results, matcherOut );
+			}
+		}
+	});
+}
+
+function matcherFromTokens( tokens ) {
+	var checkContext, matcher, j,
+		len = tokens.length,
+		leadingRelative = Expr.relative[ tokens[0].type ],
+		implicitRelative = leadingRelative || Expr.relative[" "],
+		i = leadingRelative ? 1 : 0,
+
+		// The foundational matcher ensures that elements are reachable from top-level context(s)
+		matchContext = addCombinator( function( elem ) {
+			return elem === checkContext;
+		}, implicitRelative, true ),
+		matchAnyContext = addCombinator( function( elem ) {
+			return indexOf.call( checkContext, elem ) > -1;
+		}, implicitRelative, true ),
+		matchers = [ function( elem, context, xml ) {
+			return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+				(checkContext = context).nodeType ?
+					matchContext( elem, context, xml ) :
+					matchAnyContext( elem, context, xml ) );
+		} ];
+
+	for ( ; i < len; i++ ) {
+		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+		} else {
+			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+			// Return special upon seeing a positional matcher
+			if ( matcher[ expando ] ) {
+				// Find the next relative operator (if any) for proper handling
+				j = ++i;
+				for ( ; j < len; j++ ) {
+					if ( Expr.relative[ tokens[j].type ] ) {
+						break;
+					}
+				}
+				return setMatcher(
+					i > 1 && elementMatcher( matchers ),
+					i > 1 && toSelector( tokens.slice( 0, i - 1 ) ).replace( rtrim, "$1" ),
+					matcher,
+					i < j && matcherFromTokens( tokens.slice( i, j ) ),
+					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+					j < len && toSelector( tokens )
+				);
+			}
+			matchers.push( matcher );
+		}
+	}
+
+	return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+	// A counter to specify which element is currently being matched
+	var matcherCachedRuns = 0,
+		bySet = setMatchers.length > 0,
+		byElement = elementMatchers.length > 0,
+		superMatcher = function( seed, context, xml, results, expandContext ) {
+			var elem, j, matcher,
+				setMatched = [],
+				matchedCount = 0,
+				i = "0",
+				unmatched = seed && [],
+				outermost = expandContext != null,
+				contextBackup = outermostContext,
+				// We must always have either seed elements or context
+				elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
+				// Use integer dirruns iff this is the outermost matcher
+				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1);
+
+			if ( outermost ) {
+				outermostContext = context !== document && context;
+				cachedruns = matcherCachedRuns;
+			}
+
+			// Add elements passing elementMatchers directly to results
+			// Keep `i` a string if there are no elements so `matchedCount` will be "00" below
+			for ( ; (elem = elems[i]) != null; i++ ) {
+				if ( byElement && elem ) {
+					j = 0;
+					while ( (matcher = elementMatchers[j++]) ) {
+						if ( matcher( elem, context, xml ) ) {
+							results.push( elem );
+							break;
+						}
+					}
+					if ( outermost ) {
+						dirruns = dirrunsUnique;
+						cachedruns = ++matcherCachedRuns;
+					}
+				}
+
+				// Track unmatched elements for set filters
+				if ( bySet ) {
+					// They will have gone through all possible matchers
+					if ( (elem = !matcher && elem) ) {
+						matchedCount--;
+					}
+
+					// Lengthen the array for every element, matched or not
+					if ( seed ) {
+						unmatched.push( elem );
+					}
+				}
+			}
+
+			// Apply set filters to unmatched elements
+			matchedCount += i;
+			if ( bySet && i !== matchedCount ) {
+				j = 0;
+				while ( (matcher = setMatchers[j++]) ) {
+					matcher( unmatched, setMatched, context, xml );
+				}
+
+				if ( seed ) {
+					// Reintegrate element matches to eliminate the need for sorting
+					if ( matchedCount > 0 ) {
+						while ( i-- ) {
+							if ( !(unmatched[i] || setMatched[i]) ) {
+								setMatched[i] = pop.call( results );
+							}
+						}
+					}
+
+					// Discard index placeholder values to get only actual matches
+					setMatched = condense( setMatched );
+				}
+
+				// Add matches to results
+				push.apply( results, setMatched );
+
+				// Seedless set matches succeeding multiple successful matchers stipulate sorting
+				if ( outermost && !seed && setMatched.length > 0 &&
+					( matchedCount + setMatchers.length ) > 1 ) {
+
+					Sizzle.uniqueSort( results );
+				}
+			}
+
+			// Override manipulation of globals by nested matchers
+			if ( outermost ) {
+				dirruns = dirrunsUnique;
+				outermostContext = contextBackup;
+			}
+
+			return unmatched;
+		};
+
+	return bySet ?
+		markFunction( superMatcher ) :
+		superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
+	var i,
+		setMatchers = [],
+		elementMatchers = [],
+		cached = compilerCache[ selector + " " ];
+
+	if ( !cached ) {
+		// Generate a function of recursive functions that can be used to check each element
+		if ( !group ) {
+			group = tokenize( selector );
+		}
+		i = group.length;
+		while ( i-- ) {
+			cached = matcherFromTokens( group[i] );
+			if ( cached[ expando ] ) {
+				setMatchers.push( cached );
+			} else {
+				elementMatchers.push( cached );
+			}
+		}
+
+		// Cache the compiled function
+		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+	}
+	return cached;
+};
+
+function multipleContexts( selector, contexts, results ) {
+	var i = 0,
+		len = contexts.length;
+	for ( ; i < len; i++ ) {
+		Sizzle( selector, contexts[i], results );
+	}
+	return results;
+}
+
+function select( selector, context, results, seed ) {
+	var i, tokens, token, type, find,
+		match = tokenize( selector );
+
+	if ( !seed ) {
+		// Try to minimize operations if there is only one group
+		if ( match.length === 1 ) {
+
+			// Take a shortcut and set the context if the root selector is an ID
+			tokens = match[0] = match[0].slice( 0 );
+			if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+					context.nodeType === 9 && !documentIsXML &&
+					Expr.relative[ tokens[1].type ] ) {
+
+				context = Expr.find["ID"]( token.matches[0].replace( runescape, funescape ), context )[0];
+				if ( !context ) {
+					return results;
+				}
+
+				selector = selector.slice( tokens.shift().value.length );
+			}
+
+			// Fetch a seed set for right-to-left matching
+			i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
+			while ( i-- ) {
+				token = tokens[i];
+
+				// Abort if we hit a combinator
+				if ( Expr.relative[ (type = token.type) ] ) {
+					break;
+				}
+				if ( (find = Expr.find[ type ]) ) {
+					// Search, expanding context for leading sibling combinators
+					if ( (seed = find(
+						token.matches[0].replace( runescape, funescape ),
+						rsibling.test( tokens[0].type ) && context.parentNode || context
+					)) ) {
+
+						// If seed is empty or no tokens remain, we can return early
+						tokens.splice( i, 1 );
+						selector = seed.length && toSelector( tokens );
+						if ( !selector ) {
+							push.apply( results, slice.call( seed, 0 ) );
+							return results;
+						}
+
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	// Compile and execute a filtering function
+	// Provide `match` to avoid retokenization if we modified the selector above
+	compile( selector, match )(
+		seed,
+		context,
+		documentIsXML,
+		results,
+		rsibling.test( selector )
+	);
+	return results;
+}
+
+// Deprecated
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Easy API for creating new setFilters
+function setFilters() {}
+Expr.filters = setFilters.prototype = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
+// Initialize with the default document
+setDocument();
+
+// Override sizzle attribute retrieval
+Sizzle.attr = jQuery.attr;
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.pseudos;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+})( window );
+var runtil = /Until$/,
+	rparentsprev = /^(?:parents|prev(?:Until|All))/,
+	isSimple = /^.[^:#\[\.,]*$/,
+	rneedsContext = jQuery.expr.match.needsContext,
+	// methods guaranteed to produce a unique set when starting from a unique set
+	guaranteedUnique = {
+		children: true,
+		contents: true,
+		next: true,
+		prev: true
+	};
+
+jQuery.fn.extend({
+	find: function( selector ) {
+		var i, ret, self,
+			len = this.length;
+
+		if ( typeof selector !== "string" ) {
+			self = this;
+			return this.pushStack( jQuery( selector ).filter(function() {
+				for ( i = 0; i < len; i++ ) {
+					if ( jQuery.contains( self[ i ], this ) ) {
+						return true;
+					}
+				}
+			}) );
+		}
+
+		ret = [];
+		for ( i = 0; i < len; i++ ) {
+			jQuery.find( selector, this[ i ], ret );
+		}
+
+		// Needed because $( selector, context ) becomes $( context ).find( selector )
+		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
+		ret.selector = ( this.selector ? this.selector + " " : "" ) + selector;
+		return ret;
+	},
+
+	has: function( target ) {
+		var i,
+			targets = jQuery( target, this ),
+			len = targets.length;
+
+		return this.filter(function() {
+			for ( i = 0; i < len; i++ ) {
+				if ( jQuery.contains( this, targets[i] ) ) {
+					return true;
+				}
+			}
+		});
+	},
+
+	not: function( selector ) {
+		return this.pushStack( winnow(this, selector, false) );
+	},
+
+	filter: function( selector ) {
+		return this.pushStack( winnow(this, selector, true) );
+	},
+
+	is: function( selector ) {
+		return !!selector && (
+			typeof selector === "string" ?
+				// If this is a positional/relative selector, check membership in the returned set
+				// so $("p:first").is("p:last") won't return true for a doc with two "p".
+				rneedsContext.test( selector ) ?
+					jQuery( selector, this.context ).index( this[0] ) >= 0 :
+					jQuery.filter( selector, this ).length > 0 :
+				this.filter( selector ).length > 0 );
+	},
+
+	closest: function( selectors, context ) {
+		var cur,
+			i = 0,
+			l = this.length,
+			ret = [],
+			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
+				jQuery( selectors, context || this.context ) :
+				0;
+
+		for ( ; i < l; i++ ) {
+			cur = this[i];
+
+			while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) {
+				if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
+					ret.push( cur );
+					break;
+				}
+				cur = cur.parentNode;
+			}
+		}
+
+		return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret );
+	},
+
+	// Determine the position of an element within
+	// the matched set of elements
+	index: function( elem ) {
+
+		// No argument, return index in parent
+		if ( !elem ) {
+			return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
+		}
+
+		// index in selector
+		if ( typeof elem === "string" ) {
+			return jQuery.inArray( this[0], jQuery( elem ) );
+		}
+
+		// Locate the position of the desired element
+		return jQuery.inArray(
+			// If it receives a jQuery object, the first element is used
+			elem.jquery ? elem[0] : elem, this );
+	},
+
+	add: function( selector, context ) {
+		var set = typeof selector === "string" ?
+				jQuery( selector, context ) :
+				jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
+			all = jQuery.merge( this.get(), set );
+
+		return this.pushStack( jQuery.unique(all) );
+	},
+
+	addBack: function( selector ) {
+		return this.add( selector == null ?
+			this.prevObject : this.prevObject.filter(selector)
+		);
+	}
+});
+
+jQuery.fn.andSelf = jQuery.fn.addBack;
+
+function sibling( cur, dir ) {
+	do {
+		cur = cur[ dir ];
+	} while ( cur && cur.nodeType !== 1 );
+
+	return cur;
+}
+
+jQuery.each({
+	parent: function( elem ) {
+		var parent = elem.parentNode;
+		return parent && parent.nodeType !== 11 ? parent : null;
+	},
+	parents: function( elem ) {
+		return jQuery.dir( elem, "parentNode" );
+	},
+	parentsUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "parentNode", until );
+	},
+	next: function( elem ) {
+		return sibling( elem, "nextSibling" );
+	},
+	prev: function( elem ) {
+		return sibling( elem, "previousSibling" );
+	},
+	nextAll: function( elem ) {
+		return jQuery.dir( elem, "nextSibling" );
+	},
+	prevAll: function( elem ) {
+		return jQuery.dir( elem, "previousSibling" );
+	},
+	nextUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "nextSibling", until );
+	},
+	prevUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "previousSibling", until );
+	},
+	siblings: function( elem ) {
+		return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
+	},
+	children: function( elem ) {
+		return jQuery.sibling( elem.firstChild );
+	},
+	contents: function( elem ) {
+		return jQuery.nodeName( elem, "iframe" ) ?
+			elem.contentDocument || elem.contentWindow.document :
+			jQuery.merge( [], elem.childNodes );
+	}
+}, function( name, fn ) {
+	jQuery.fn[ name ] = function( until, selector ) {
+		var ret = jQuery.map( this, fn, until );
+
+		if ( !runtil.test( name ) ) {
+			selector = until;
+		}
+
+		if ( selector && typeof selector === "string" ) {
+			ret = jQuery.filter( selector, ret );
+		}
+
+		ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
+
+		if ( this.length > 1 && rparentsprev.test( name ) ) {
+			ret = ret.reverse();
+		}
+
+		return this.pushStack( ret );
+	};
+});
+
+jQuery.extend({
+	filter: function( expr, elems, not ) {
+		if ( not ) {
+			expr = ":not(" + expr + ")";
+		}
+
+		return elems.length === 1 ?
+			jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
+			jQuery.find.matches(expr, elems);
+	},
+
+	dir: function( elem, dir, until ) {
+		var matched = [],
+			cur = elem[ dir ];
+
+		while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+			if ( cur.nodeType === 1 ) {
+				matched.push( cur );
+			}
+			cur = cur[dir];
+		}
+		return matched;
+	},
+
+	sibling: function( n, elem ) {
+		var r = [];
+
+		for ( ; n; n = n.nextSibling ) {
+			if ( n.nodeType === 1 && n !== elem ) {
+				r.push( n );
+			}
+		}
+
+		return r;
+	}
+});
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, keep ) {
+
+	// Can't pass null or undefined to indexOf in Firefox 4
+	// Set to 0 to skip string check
+	qualifier = qualifier || 0;
+
+	if ( jQuery.isFunction( qualifier ) ) {
+		return jQuery.grep(elements, function( elem, i ) {
+			var retVal = !!qualifier.call( elem, i, elem );
+			return retVal === keep;
+		});
+
+	} else if ( qualifier.nodeType ) {
+		return jQuery.grep(elements, function( elem ) {
+			return ( elem === qualifier ) === keep;
+		});
+
+	} else if ( typeof qualifier === "string" ) {
+		var filtered = jQuery.grep(elements, function( elem ) {
+			return elem.nodeType === 1;
+		});
+
+		if ( isSimple.test( qualifier ) ) {
+			return jQuery.filter(qualifier, filtered, !keep);
+		} else {
+			qualifier = jQuery.filter( qualifier, filtered );
+		}
+	}
+
+	return jQuery.grep(elements, function( elem ) {
+		return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
+	});
+}
+function createSafeFragment( document ) {
+	var list = nodeNames.split( "|" ),
+		safeFrag = document.createDocumentFragment();
+
+	if ( safeFrag.createElement ) {
+		while ( list.length ) {
+			safeFrag.createElement(
+				list.pop()
+			);
+		}
+	}
+	return safeFrag;
+}
+
+var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
+		"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
+	rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
+	rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
+	rleadingWhitespace = /^\s+/,
+	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
+	rtagName = /<([\w:]+)/,
+	rtbody = /<tbody/i,
+	rhtml = /<|&#?\w+;/,
+	rnoInnerhtml = /<(?:script|style|link)/i,
+	manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
+	// checked="checked" or checked
+	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+	rscriptType = /^$|\/(?:java|ecma)script/i,
+	rscriptTypeMasked = /^true\/(.*)/,
+	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
+
+	// We have to close these tags to support XHTML (#13200)
+	wrapMap = {
+		option: [ 1, "<select multiple='multiple'>", "</select>" ],
+		legend: [ 1, "<fieldset>", "</fieldset>" ],
+		area: [ 1, "<map>", "</map>" ],
+		param: [ 1, "<object>", "</object>" ],
+		thead: [ 1, "<table>", "</table>" ],
+		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+
+		// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
+		// unless wrapped in a div with non-breaking characters in front of it.
+		_default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>"  ]
+	},
+	safeFragment = createSafeFragment( document ),
+	fragmentDiv = safeFragment.appendChild( document.createElement("div") );
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+jQuery.fn.extend({
+	text: function( value ) {
+		return jQuery.access( this, function( value ) {
+			return value === undefined ?
+				jQuery.text( this ) :
+				this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
+		}, null, value, arguments.length );
+	},
+
+	wrapAll: function( html ) {
+		if ( jQuery.isFunction( html ) ) {
+			return this.each(function(i) {
+				jQuery(this).wrapAll( html.call(this, i) );
+			});
+		}
+
+		if ( this[0] ) {
+			// The elements to wrap the target around
+			var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+			if ( this[0].parentNode ) {
+				wrap.insertBefore( this[0] );
+			}
+
+			wrap.map(function() {
+				var elem = this;
+
+				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+					elem = elem.firstChild;
+				}
+
+				return elem;
+			}).append( this );
+		}
+
+		return this;
+	},
+
+	wrapInner: function( html ) {
+		if ( jQuery.isFunction( html ) ) {
+			return this.each(function(i) {
+				jQuery(this).wrapInner( html.call(this, i) );
+			});
+		}
+
+		return this.each(function() {
+			var self = jQuery( this ),
+				contents = self.contents();
+
+			if ( contents.length ) {
+				contents.wrapAll( html );
+
+			} else {
+				self.append( html );
+			}
+		});
+	},
+
+	wrap: function( html ) {
+		var isFunction = jQuery.isFunction( html );
+
+		return this.each(function(i) {
+			jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
+		});
+	},
+
+	unwrap: function() {
+		return this.parent().each(function() {
+			if ( !jQuery.nodeName( this, "body" ) ) {
+				jQuery( this ).replaceWith( this.childNodes );
+			}
+		}).end();
+	},
+
+	append: function() {
+		return this.domManip(arguments, true, function( elem ) {
+			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+				this.appendChild( elem );
+			}
+		});
+	},
+
+	prepend: function() {
+		return this.domManip(arguments, true, function( elem ) {
+			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+				this.insertBefore( elem, this.firstChild );
+			}
+		});
+	},
+
+	before: function() {
+		return this.domManip( arguments, false, function( elem ) {
+			if ( this.parentNode ) {
+				this.parentNode.insertBefore( elem, this );
+			}
+		});
+	},
+
+	after: function() {
+		return this.domManip( arguments, false, function( elem ) {
+			if ( this.parentNode ) {
+				this.parentNode.insertBefore( elem, this.nextSibling );
+			}
+		});
+	},
+
+	// keepData is for internal use only--do not document
+	remove: function( selector, keepData ) {
+		var elem,
+			i = 0;
+
+		for ( ; (elem = this[i]) != null; i++ ) {
+			if ( !selector || jQuery.filter( selector, [ elem ] ).length > 0 ) {
+				if ( !keepData && elem.nodeType === 1 ) {
+					jQuery.cleanData( getAll( elem ) );
+				}
+
+				if ( elem.parentNode ) {
+					if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
+						setGlobalEval( getAll( elem, "script" ) );
+					}
+					elem.parentNode.removeChild( elem );
+				}
+			}
+		}
+
+		return this;
+	},
+
+	empty: function() {
+		var elem,
+			i = 0;
+
+		for ( ; (elem = this[i]) != null; i++ ) {
+			// Remove element nodes and prevent memory leaks
+			if ( elem.nodeType === 1 ) {
+				jQuery.cleanData( getAll( elem, false ) );
+			}
+
+			// Remove any remaining nodes
+			while ( elem.firstChild ) {
+				elem.removeChild( elem.firstChild );
+			}
+
+			// If this is a select, ensure that it displays empty (#12336)
+			// Support: IE<9
+			if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
+				elem.options.length = 0;
+			}
+		}
+
+		return this;
+	},
+
+	clone: function( dataAndEvents, deepDataAndEvents ) {
+		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+		return this.map( function () {
+			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+		});
+	},
+
+	html: function( value ) {
+		return jQuery.access( this, function( value ) {
+			var elem = this[0] || {},
+				i = 0,
+				l = this.length;
+
+			if ( value === undefined ) {
+				return elem.nodeType === 1 ?
+					elem.innerHTML.replace( rinlinejQuery, "" ) :
+					undefined;
+			}
+
+			// See if we can take a shortcut and just use innerHTML
+			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
+				( jQuery.support.htmlSerialize || !rnoshimcache.test( value )  ) &&
+				( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
+				!wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {
+
+				value = value.replace( rxhtmlTag, "<$1></$2>" );
+
+				try {
+					for (; i < l; i++ ) {
+						// Remove element nodes and prevent memory leaks
+						elem = this[i] || {};
+						if ( elem.nodeType === 1 ) {
+							jQuery.cleanData( getAll( elem, false ) );
+							elem.innerHTML = value;
+						}
+					}
+
+					elem = 0;
+
+				// If using innerHTML throws an exception, use the fallback method
+				} catch(e) {}
+			}
+
+			if ( elem ) {
+				this.empty().append( value );
+			}
+		}, null, value, arguments.length );
+	},
+
+	replaceWith: function( value ) {
+		var isFunc = jQuery.isFunction( value );
+
+		// Make sure that the elements are removed from the DOM before they are inserted
+		// this can help fix replacing a parent with child elements
+		if ( !isFunc && typeof value !== "string" ) {
+			value = jQuery( value ).not( this ).detach();
+		}
+
+		return this.domManip( [ value ], true, function( elem ) {
+			var next = this.nextSibling,
+				parent = this.parentNode;
+
+			if ( parent ) {
+				jQuery( this ).remove();
+				parent.insertBefore( elem, next );
+			}
+		});
+	},
+
+	detach: function( selector ) {
+		return this.remove( selector, true );
+	},
+
+	domManip: function( args, table, callback ) {
+
+		// Flatten any nested arrays
+		args = core_concat.apply( [], args );
+
+		var first, node, hasScripts,
+			scripts, doc, fragment,
+			i = 0,
+			l = this.length,
+			set = this,
+			iNoClone = l - 1,
+			value = args[0],
+			isFunction = jQuery.isFunction( value );
+
+		// We can't cloneNode fragments that contain checked, in WebKit
+		if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) {
+			return this.each(function( index ) {
+				var self = set.eq( index );
+				if ( isFunction ) {
+					args[0] = value.call( this, index, table ? self.html() : undefined );
+				}
+				self.domManip( args, table, callback );
+			});
+		}
+
+		if ( l ) {
+			fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
+			first = fragment.firstChild;
+
+			if ( fragment.childNodes.length === 1 ) {
+				fragment = first;
+			}
+
+			if ( first ) {
+				table = table && jQuery.nodeName( first, "tr" );
+				scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
+				hasScripts = scripts.length;
+
+				// Use the original fragment for the last item instead of the first because it can end up
+				// being emptied incorrectly in certain situations (#8070).
+				for ( ; i < l; i++ ) {
+					node = fragment;
+
+					if ( i !== iNoClone ) {
+						node = jQuery.clone( node, true, true );
+
+						// Keep references to cloned scripts for later restoration
+						if ( hasScripts ) {
+							jQuery.merge( scripts, getAll( node, "script" ) );
+						}
+					}
+
+					callback.call(
+						table && jQuery.nodeName( this[i], "table" ) ?
+							findOrAppend( this[i], "tbody" ) :
+							this[i],
+						node,
+						i
+					);
+				}
+
+				if ( hasScripts ) {
+					doc = scripts[ scripts.length - 1 ].ownerDocument;
+
+					// Reenable scripts
+					jQuery.map( scripts, restoreScript );
+
+					// Evaluate executable scripts on first document insertion
+					for ( i = 0; i < hasScripts; i++ ) {
+						node = scripts[ i ];
+						if ( rscriptType.test( node.type || "" ) &&
+							!jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
+
+							if ( node.src ) {
+								// Hope ajax is available...
+								jQuery.ajax({
+									url: node.src,
+									type: "GET",
+									dataType: "script",
+									async: false,
+									global: false,
+									"throws": true
+								});
+							} else {
+								jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
+							}
+						}
+					}
+				}
+
+				// Fix #11809: Avoid leaking memory
+				fragment = first = null;
+			}
+		}
+
+		return this;
+	}
+});
+
+function findOrAppend( elem, tag ) {
+	return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) );
+}
+
+// Replace/restore the type attribute of script elements for safe DOM manipulation
+function disableScript( elem ) {
+	var attr = elem.getAttributeNode("type");
+	elem.type = ( attr && attr.specified ) + "/" + elem.type;
+	return elem;
+}
+function restoreScript( elem ) {
+	var match = rscriptTypeMasked.exec( elem.type );
+	if ( match ) {
+		elem.type = match[1];
+	} else {
+		elem.removeAttribute("type");
+	}
+	return elem;
+}
+
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+	var elem,
+		i = 0;
+	for ( ; (elem = elems[i]) != null; i++ ) {
+		jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) );
+	}
+}
+
+function cloneCopyEvent( src, dest ) {
+
+	if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
+		return;
+	}
+
+	var type, i, l,
+		oldData = jQuery._data( src ),
+		curData = jQuery._data( dest, oldData ),
+		events = oldData.events;
+
+	if ( events ) {
+		delete curData.handle;
+		curData.events = {};
+
+		for ( type in events ) {
+			for ( i = 0, l = events[ type ].length; i < l; i++ ) {
+				jQuery.event.add( dest, type, events[ type ][ i ] );
+			}
+		}
+	}
+
+	// make the cloned public data object a copy from the original
+	if ( curData.data ) {
+		curData.data = jQuery.extend( {}, curData.data );
+	}
+}
+
+function fixCloneNodeIssues( src, dest ) {
+	var nodeName, e, data;
+
+	// We do not need to do anything for non-Elements
+	if ( dest.nodeType !== 1 ) {
+		return;
+	}
+
+	nodeName = dest.nodeName.toLowerCase();
+
+	// IE6-8 copies events bound via attachEvent when using cloneNode.
+	if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) {
+		data = jQuery._data( dest );
+
+		for ( e in data.events ) {
+			jQuery.removeEvent( dest, e, data.handle );
+		}
+
+		// Event data gets referenced instead of copied if the expando gets copied too
+		dest.removeAttribute( jQuery.expando );
+	}
+
+	// IE blanks contents when cloning scripts, and tries to evaluate newly-set text
+	if ( nodeName === "script" && dest.text !== src.text ) {
+		disableScript( dest ).text = src.text;
+		restoreScript( dest );
+
+	// IE6-10 improperly clones children of object elements using classid.
+	// IE10 throws NoModificationAllowedError if parent is null, #12132.
+	} else if ( nodeName === "object" ) {
+		if ( dest.parentNode ) {
+			dest.outerHTML = src.outerHTML;
+		}
+
+		// This path appears unavoidable for IE9. When cloning an object
+		// element in IE9, the outerHTML strategy above is not sufficient.
+		// If the src has innerHTML and the destination does not,
+		// copy the src.innerHTML into the dest.innerHTML. #10324
+		if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {
+			dest.innerHTML = src.innerHTML;
+		}
+
+	} else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) {
+		// IE6-8 fails to persist the checked state of a cloned checkbox
+		// or radio button. Worse, IE6-7 fail to give the cloned element
+		// a checked appearance if the defaultChecked value isn't also set
+
+		dest.defaultChecked = dest.checked = src.checked;
+
+		// IE6-7 get confused and end up setting the value of a cloned
+		// checkbox/radio button to an empty string instead of "on"
+		if ( dest.value !== src.value ) {
+			dest.value = src.value;
+		}
+
+	// IE6-8 fails to return the selected option to the default selected
+	// state when cloning options
+	} else if ( nodeName === "option" ) {
+		dest.defaultSelected = dest.selected = src.defaultSelected;
+
+	// IE6-8 fails to set the defaultValue to the correct value when
+	// cloning other types of input fields
+	} else if ( nodeName === "input" || nodeName === "textarea" ) {
+		dest.defaultValue = src.defaultValue;
+	}
+}
+
+jQuery.each({
+	appendTo: "append",
+	prependTo: "prepend",
+	insertBefore: "before",
+	insertAfter: "after",
+	replaceAll: "replaceWith"
+}, function( name, original ) {
+	jQuery.fn[ name ] = function( selector ) {
+		var elems,
+			i = 0,
+			ret = [],
+			insert = jQuery( selector ),
+			last = insert.length - 1;
+
+		for ( ; i <= last; i++ ) {
+			elems = i === last ? this : this.clone(true);
+			jQuery( insert[i] )[ original ]( elems );
+
+			// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
+			core_push.apply( ret, elems.get() );
+		}
+
+		return this.pushStack( ret );
+	};
+});
+
+function getAll( context, tag ) {
+	var elems, elem,
+		i = 0,
+		found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) :
+			typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) :
+			undefined;
+
+	if ( !found ) {
+		for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
+			if ( !tag || jQuery.nodeName( elem, tag ) ) {
+				found.push( elem );
+			} else {
+				jQuery.merge( found, getAll( elem, tag ) );
+			}
+		}
+	}
+
+	return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
+		jQuery.merge( [ context ], found ) :
+		found;
+}
+
+// Used in buildFragment, fixes the defaultChecked property
+function fixDefaultChecked( elem ) {
+	if ( manipulation_rcheckableType.test( elem.type ) ) {
+		elem.defaultChecked = elem.checked;
+	}
+}
+
+jQuery.extend({
+	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+		var destElements, node, clone, i, srcElements,
+			inPage = jQuery.contains( elem.ownerDocument, elem );
+
+		if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
+			clone = elem.cloneNode( true );
+
+		// IE<=8 does not properly clone detached, unknown element nodes
+		} else {
+			fragmentDiv.innerHTML = elem.outerHTML;
+			fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
+		}
+
+		if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
+				(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
+
+			// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
+			destElements = getAll( clone );
+			srcElements = getAll( elem );
+
+			// Fix all IE cloning issues
+			for ( i = 0; (node = srcElements[i]) != null; ++i ) {
+				// Ensure that the destination node is not null; Fixes #9587
+				if ( destElements[i] ) {
+					fixCloneNodeIssues( node, destElements[i] );
+				}
+			}
+		}
+
+		// Copy the events from the original to the clone
+		if ( dataAndEvents ) {
+			if ( deepDataAndEvents ) {
+				srcElements = srcElements || getAll( elem );
+				destElements = destElements || getAll( clone );
+
+				for ( i = 0; (node = srcElements[i]) != null; i++ ) {
+					cloneCopyEvent( node, destElements[i] );
+				}
+			} else {
+				cloneCopyEvent( elem, clone );
+			}
+		}
+
+		// Preserve script evaluation history
+		destElements = getAll( clone, "script" );
+		if ( destElements.length > 0 ) {
+			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
+		}
+
+		destElements = srcElements = node = null;
+
+		// Return the cloned set
+		return clone;
+	},
+
+	buildFragment: function( elems, context, scripts, selection ) {
+		var j, elem, contains,
+			tmp, tag, tbody, wrap,
+			l = elems.length,
+
+			// Ensure a safe fragment
+			safe = createSafeFragment( context ),
+
+			nodes = [],
+			i = 0;
+
+		for ( ; i < l; i++ ) {
+			elem = elems[ i ];
+
+			if ( elem || elem === 0 ) {
+
+				// Add nodes directly
+				if ( jQuery.type( elem ) === "object" ) {
+					jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
+
+				// Convert non-html into a text node
+				} else if ( !rhtml.test( elem ) ) {
+					nodes.push( context.createTextNode( elem ) );
+
+				// Convert html into DOM nodes
+				} else {
+					tmp = tmp || safe.appendChild( context.createElement("div") );
+
+					// Deserialize a standard representation
+					tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase();
+					wrap = wrapMap[ tag ] || wrapMap._default;
+
+					tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2];
+
+					// Descend through wrappers to the right content
+					j = wrap[0];
+					while ( j-- ) {
+						tmp = tmp.lastChild;
+					}
+
+					// Manually add leading whitespace removed by IE
+					if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+						nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
+					}
+
+					// Remove IE's autoinserted <tbody> from table fragments
+					if ( !jQuery.support.tbody ) {
+
+						// String was a <table>, *may* have spurious <tbody>
+						elem = tag === "table" && !rtbody.test( elem ) ?
+							tmp.firstChild :
+
+							// String was a bare <thead> or <tfoot>
+							wrap[1] === "<table>" && !rtbody.test( elem ) ?
+								tmp :
+								0;
+
+						j = elem && elem.childNodes.length;
+						while ( j-- ) {
+							if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
+								elem.removeChild( tbody );
+							}
+						}
+					}
+
+					jQuery.merge( nodes, tmp.childNodes );
+
+					// Fix #12392 for WebKit and IE > 9
+					tmp.textContent = "";
+
+					// Fix #12392 for oldIE
+					while ( tmp.firstChild ) {
+						tmp.removeChild( tmp.firstChild );
+					}
+
+					// Remember the top-level container for proper cleanup
+					tmp = safe.lastChild;
+				}
+			}
+		}
+
+		// Fix #11356: Clear elements from fragment
+		if ( tmp ) {
+			safe.removeChild( tmp );
+		}
+
+		// Reset defaultChecked for any radios and checkboxes
+		// about to be appended to the DOM in IE 6/7 (#8060)
+		if ( !jQuery.support.appendChecked ) {
+			jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
+		}
+
+		i = 0;
+		while ( (elem = nodes[ i++ ]) ) {
+
+			// #4087 - If origin and destination elements are the same, and this is
+			// that element, do not do anything
+			if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
+				continue;
+			}
+
+			contains = jQuery.contains( elem.ownerDocument, elem );
+
+			// Append to fragment
+			tmp = getAll( safe.appendChild( elem ), "script" );
+
+			// Preserve script evaluation history
+			if ( contains ) {
+				setGlobalEval( tmp );
+			}
+
+			// Capture executables
+			if ( scripts ) {
+				j = 0;
+				while ( (elem = tmp[ j++ ]) ) {
+					if ( rscriptType.test( elem.type || "" ) ) {
+						scripts.push( elem );
+					}
+				}
+			}
+		}
+
+		tmp = null;
+
+		return safe;
+	},
+
+	cleanData: function( elems, /* internal */ acceptData ) {
+		var elem, type, id, data,
+			i = 0,
+			internalKey = jQuery.expando,
+			cache = jQuery.cache,
+			deleteExpando = jQuery.support.deleteExpando,
+			special = jQuery.event.special;
+
+		for ( ; (elem = elems[i]) != null; i++ ) {
+
+			if ( acceptData || jQuery.acceptData( elem ) ) {
+
+				id = elem[ internalKey ];
+				data = id && cache[ id ];
+
+				if ( data ) {
+					if ( data.events ) {
+						for ( type in data.events ) {
+							if ( special[ type ] ) {
+								jQuery.event.remove( elem, type );
+
+							// This is a shortcut to avoid jQuery.event.remove's overhead
+							} else {
+								jQuery.removeEvent( elem, type, data.handle );
+							}
+						}
+					}
+
+					// Remove cache only if it was not already removed by jQuery.event.remove
+					if ( cache[ id ] ) {
+
+						delete cache[ id ];
+
+						// IE does not allow us to delete expando properties from nodes,
+						// nor does it have a removeAttribute function on Document nodes;
+						// we must handle all of these cases
+						if ( deleteExpando ) {
+							delete elem[ internalKey ];
+
+						} else if ( typeof elem.removeAttribute !== core_strundefined ) {
+							elem.removeAttribute( internalKey );
+
+						} else {
+							elem[ internalKey ] = null;
+						}
+
+						core_deletedIds.push( id );
+					}
+				}
+			}
+		}
+	}
+});
+var iframe, getStyles, curCSS,
+	ralpha = /alpha\([^)]*\)/i,
+	ropacity = /opacity\s*=\s*([^)]*)/,
+	rposition = /^(top|right|bottom|left)$/,
+	// swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
+	// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
+	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
+	rmargin = /^margin/,
+	rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
+	rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
+	rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ),
+	elemdisplay = { BODY: "block" },
+
+	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+	cssNormalTransform = {
+		letterSpacing: 0,
+		fontWeight: 400
+	},
+
+	cssExpand = [ "Top", "Right", "Bottom", "Left" ],
+	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
+
+// return a css property mapped to a potentially vendor prefixed property
+function vendorPropName( style, name ) {
+
+	// shortcut for names that are not vendor prefixed
+	if ( name in style ) {
+		return name;
+	}
+
+	// check for vendor prefixed names
+	var capName = name.charAt(0).toUpperCase() + name.slice(1),
+		origName = name,
+		i = cssPrefixes.length;
+
+	while ( i-- ) {
+		name = cssPrefixes[ i ] + capName;
+		if ( name in style ) {
+			return name;
+		}
+	}
+
+	return origName;
+}
+
+function isHidden( elem, el ) {
+	// isHidden might be called from jQuery#filter function;
+	// in that case, element will be second argument
+	elem = el || elem;
+	return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
+}
+
+function showHide( elements, show ) {
+	var display, elem, hidden,
+		values = [],
+		index = 0,
+		length = elements.length;
+
+	for ( ; index < length; index++ ) {
+		elem = elements[ index ];
+		if ( !elem.style ) {
+			continue;
+		}
+
+		values[ index ] = jQuery._data( elem, "olddisplay" );
+		display = elem.style.display;
+		if ( show ) {
+			// Reset the inline display of this element to learn if it is
+			// being hidden by cascaded rules or not
+			if ( !values[ index ] && display === "none" ) {
+				elem.style.display = "";
+			}
+
+			// Set elements which have been overridden with display: none
+			// in a stylesheet to whatever the default browser style is
+			// for such an element
+			if ( elem.style.display === "" && isHidden( elem ) ) {
+				values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
+			}
+		} else {
+
+			if ( !values[ index ] ) {
+				hidden = isHidden( elem );
+
+				if ( display && display !== "none" || !hidden ) {
+					jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
+				}
+			}
+		}
+	}
+
+	// Set the display of most of the elements in a second loop
+	// to avoid the constant reflow
+	for ( index = 0; index < length; index++ ) {
+		elem = elements[ index ];
+		if ( !elem.style ) {
+			continue;
+		}
+		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
+			elem.style.display = show ? values[ index ] || "" : "none";
+		}
+	}
+
+	return elements;
+}
+
+jQuery.fn.extend({
+	css: function( name, value ) {
+		return jQuery.access( this, function( elem, name, value ) {
+			var len, styles,
+				map = {},
+				i = 0;
+
+			if ( jQuery.isArray( name ) ) {
+				styles = getStyles( elem );
+				len = name.length;
+
+				for ( ; i < len; i++ ) {
+					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
+				}
+
+				return map;
+			}
+
+			return value !== undefined ?
+				jQuery.style( elem, name, value ) :
+				jQuery.css( elem, name );
+		}, name, value, arguments.length > 1 );
+	},
+	show: function() {
+		return showHide( this, true );
+	},
+	hide: function() {
+		return showHide( this );
+	},
+	toggle: function( state ) {
+		var bool = typeof state === "boolean";
+
+		return this.each(function() {
+			if ( bool ? state : isHidden( this ) ) {
+				jQuery( this ).show();
+			} else {
+				jQuery( this ).hide();
+			}
+		});
+	}
+});
+
+jQuery.extend({
+	// Add in style property hooks for overriding the default
+	// behavior of getting and setting a style property
+	cssHooks: {
+		opacity: {
+			get: function( elem, computed ) {
+				if ( computed ) {
+					// We should always get a number back from opacity
+					var ret = curCSS( elem, "opacity" );
+					return ret === "" ? "1" : ret;
+				}
+			}
+		}
+	},
+
+	// Exclude the following css properties to add px
+	cssNumber: {
+		"columnCount": true,
+		"fillOpacity": true,
+		"fontWeight": true,
+		"lineHeight": true,
+		"opacity": true,
+		"orphans": true,
+		"widows": true,
+		"zIndex": true,
+		"zoom": true
+	},
+
+	// Add in properties whose names you wish to fix before
+	// setting or getting the value
+	cssProps: {
+		// normalize float css property
+		"float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
+	},
+
+	// Get and set the style property on a DOM Node
+	style: function( elem, name, value, extra ) {
+		// Don't set styles on text and comment nodes
+		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+			return;
+		}
+
+		// Make sure that we're working with the right name
+		var ret, type, hooks,
+			origName = jQuery.camelCase( name ),
+			style = elem.style;
+
+		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
+
+		// gets hook for the prefixed version
+		// followed by the unprefixed version
+		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+		// Check if we're setting a value
+		if ( value !== undefined ) {
+			type = typeof value;
+
+			// convert relative number strings (+= or -=) to relative numbers. #7345
+			if ( type === "string" && (ret = rrelNum.exec( value )) ) {
+				value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
+				// Fixes bug #9237
+				type = "number";
+			}
+
+			// Make sure that NaN and null values aren't set. See: #7116
+			if ( value == null || type === "number" && isNaN( value ) ) {
+				return;
+			}
+
+			// If a number was passed in, add 'px' to the (except for certain CSS properties)
+			if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
+				value += "px";
+			}
+
+			// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
+			// but it would mean to define eight (for every problematic property) identical functions
+			if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
+				style[ name ] = "inherit";
+			}
+
+			// If a hook was provided, use that value, otherwise just set the specified value
+			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
+
+				// Wrapped to prevent IE from throwing errors when 'invalid' values are provided
+				// Fixes bug #5509
+				try {
+					style[ name ] = value;
+				} catch(e) {}
+			}
+
+		} else {
+			// If a hook was provided get the non-computed value from there
+			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
+				return ret;
+			}
+
+			// Otherwise just get the value from the style object
+			return style[ name ];
+		}
+	},
+
+	css: function( elem, name, extra, styles ) {
+		var num, val, hooks,
+			origName = jQuery.camelCase( name );
+
+		// Make sure that we're working with the right name
+		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
+
+		// gets hook for the prefixed version
+		// followed by the unprefixed version
+		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+		// If a hook was provided get the computed value from there
+		if ( hooks && "get" in hooks ) {
+			val = hooks.get( elem, true, extra );
+		}
+
+		// Otherwise, if a way to get the computed value exists, use that
+		if ( val === undefined ) {
+			val = curCSS( elem, name, styles );
+		}
+
+		//convert "normal" to computed value
+		if ( val === "normal" && name in cssNormalTransform ) {
+			val = cssNormalTransform[ name ];
+		}
+
+		// Return, converting to number if forced or a qualifier was provided and val looks numeric
+		if ( extra === "" || extra ) {
+			num = parseFloat( val );
+			return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
+		}
+		return val;
+	},
+
+	// A method for quickly swapping in/out CSS properties to get correct calculations
+	swap: function( elem, options, callback, args ) {
+		var ret, name,
+			old = {};
+
+		// Remember the old values, and insert the new ones
+		for ( name in options ) {
+			old[ name ] = elem.style[ name ];
+			elem.style[ name ] = options[ name ];
+		}
+
+		ret = callback.apply( elem, args || [] );
+
+		// Revert the old values
+		for ( name in options ) {
+			elem.style[ name ] = old[ name ];
+		}
+
+		return ret;
+	}
+});
+
+// NOTE: we've included the "window" in window.getComputedStyle
+// because jsdom on node.js will break without it.
+if ( window.getComputedStyle ) {
+	getStyles = function( elem ) {
+		return window.getComputedStyle( elem, null );
+	};
+
+	curCSS = function( elem, name, _computed ) {
+		var width, minWidth, maxWidth,
+			computed = _computed || getStyles( elem ),
+
+			// getPropertyValue is only needed for .css('filter') in IE9, see #12537
+			ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
+			style = elem.style;
+
+		if ( computed ) {
+
+			if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
+				ret = jQuery.style( elem, name );
+			}
+
+			// A tribute to the "awesome hack by Dean Edwards"
+			// Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
+			// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
+			// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
+			if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
+
+				// Remember the original values
+				width = style.width;
+				minWidth = style.minWidth;
+				maxWidth = style.maxWidth;
+
+				// Put in the new values to get a computed value out
+				style.minWidth = style.maxWidth = style.width = ret;
+				ret = computed.width;
+
+				// Revert the changed values
+				style.width = width;
+				style.minWidth = minWidth;
+				style.maxWidth = maxWidth;
+			}
+		}
+
+		return ret;
+	};
+} else if ( document.documentElement.currentStyle ) {
+	getStyles = function( elem ) {
+		return elem.currentStyle;
+	};
+
+	curCSS = function( elem, name, _computed ) {
+		var left, rs, rsLeft,
+			computed = _computed || getStyles( elem ),
+			ret = computed ? computed[ name ] : undefined,
+			style = elem.style;
+
+		// Avoid setting ret to empty string here
+		// so we don't default to auto
+		if ( ret == null && style && style[ name ] ) {
+			ret = style[ name ];
+		}
+
+		// From the awesome hack by Dean Edwards
+		// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+		// If we're not dealing with a regular pixel number
+		// but a number that has a weird ending, we need to convert it to pixels
+		// but not position css attributes, as those are proportional to the parent element instead
+		// and we can't measure the parent instead because it might trigger a "stacking dolls" problem
+		if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
+
+			// Remember the original values
+			left = style.left;
+			rs = elem.runtimeStyle;
+			rsLeft = rs && rs.left;
+
+			// Put in the new values to get a computed value out
+			if ( rsLeft ) {
+				rs.left = elem.currentStyle.left;
+			}
+			style.left = name === "fontSize" ? "1em" : ret;
+			ret = style.pixelLeft + "px";
+
+			// Revert the changed values
+			style.left = left;
+			if ( rsLeft ) {
+				rs.left = rsLeft;
+			}
+		}
+
+		return ret === "" ? "auto" : ret;
+	};
+}
+
+function setPositiveNumber( elem, value, subtract ) {
+	var matches = rnumsplit.exec( value );
+	return matches ?
+		// Guard against undefined "subtract", e.g., when used as in cssHooks
+		Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
+		value;
+}
+
+function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
+	var i = extra === ( isBorderBox ? "border" : "content" ) ?
+		// If we already have the right measurement, avoid augmentation
+		4 :
+		// Otherwise initialize for horizontal or vertical properties
+		name === "width" ? 1 : 0,
+
+		val = 0;
+
+	for ( ; i < 4; i += 2 ) {
+		// both box models exclude margin, so add it if we want it
+		if ( extra === "margin" ) {
+			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
+		}
+
+		if ( isBorderBox ) {
+			// border-box includes padding, so remove it if we want content
+			if ( extra === "content" ) {
+				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+			}
+
+			// at this point, extra isn't border nor margin, so remove border
+			if ( extra !== "margin" ) {
+				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+			}
+		} else {
+			// at this point, extra isn't content, so add padding
+			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+
+			// at this point, extra isn't content nor padding, so add border
+			if ( extra !== "padding" ) {
+				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+			}
+		}
+	}
+
+	return val;
+}
+
+function getWidthOrHeight( elem, name, extra ) {
+
+	// Start with offset property, which is equivalent to the border-box value
+	var valueIsBorderBox = true,
+		val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
+		styles = getStyles( elem ),
+		isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
+
+	// some non-html elements return undefined for offsetWidth, so check for null/undefined
+	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
+	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
+	if ( val <= 0 || val == null ) {
+		// Fall back to computed then uncomputed css if necessary
+		val = curCSS( elem, name, styles );
+		if ( val < 0 || val == null ) {
+			val = elem.style[ name ];
+		}
+
+		// Computed unit is not pixels. Stop here and return.
+		if ( rnumnonpx.test(val) ) {
+			return val;
+		}
+
+		// we need the check for style in case a browser which returns unreliable values
+		// for getComputedStyle silently falls back to the reliable elem.style
+		valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
+
+		// Normalize "", auto, and prepare for extra
+		val = parseFloat( val ) || 0;
+	}
+
+	// use the active box-sizing model to add/subtract irrelevant styles
+	return ( val +
+		augmentWidthOrHeight(
+			elem,
+			name,
+			extra || ( isBorderBox ? "border" : "content" ),
+			valueIsBorderBox,
+			styles
+		)
+	) + "px";
+}
+
+// Try to determine the default display value of an element
+function css_defaultDisplay( nodeName ) {
+	var doc = document,
+		display = elemdisplay[ nodeName ];
+
+	if ( !display ) {
+		display = actualDisplay( nodeName, doc );
+
+		// If the simple way fails, read from inside an iframe
+		if ( display === "none" || !display ) {
+			// Use the already-created iframe if possible
+			iframe = ( iframe ||
+				jQuery("<iframe frameborder='0' width='0' height='0'/>")
+				.css( "cssText", "display:block !important" )
+			).appendTo( doc.documentElement );
+
+			// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
+			doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
+			doc.write("<!doctype html><html><body>");
+			doc.close();
+
+			display = actualDisplay( nodeName, doc );
+			iframe.detach();
+		}
+
+		// Store the correct default display
+		elemdisplay[ nodeName ] = display;
+	}
+
+	return display;
+}
+
+// Called ONLY from within css_defaultDisplay
+function actualDisplay( name, doc ) {
+	var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
+		display = jQuery.css( elem[0], "display" );
+	elem.remove();
+	return display;
+}
+
+jQuery.each([ "height", "width" ], function( i, name ) {
+	jQuery.cssHooks[ name ] = {
+		get: function( elem, computed, extra ) {
+			if ( computed ) {
+				// certain elements can have dimension info if we invisibly show them
+				// however, it must have a current display style that would benefit from this
+				return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ?
+					jQuery.swap( elem, cssShow, function() {
+						return getWidthOrHeight( elem, name, extra );
+					}) :
+					getWidthOrHeight( elem, name, extra );
+			}
+		},
+
+		set: function( elem, value, extra ) {
+			var styles = extra && getStyles( elem );
+			return setPositiveNumber( elem, value, extra ?
+				augmentWidthOrHeight(
+					elem,
+					name,
+					extra,
+					jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+					styles
+				) : 0
+			);
+		}
+	};
+});
+
+if ( !jQuery.support.opacity ) {
+	jQuery.cssHooks.opacity = {
+		get: function( elem, computed ) {
+			// IE uses filters for opacity
+			return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
+				( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
+				computed ? "1" : "";
+		},
+
+		set: function( elem, value ) {
+			var style = elem.style,
+				currentStyle = elem.currentStyle,
+				opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
+				filter = currentStyle && currentStyle.filter || style.filter || "";
+
+			// IE has trouble with opacity if it does not have layout
+			// Force it by setting the zoom level
+			style.zoom = 1;
+
+			// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
+			// if value === "", then remove inline opacity #12685
+			if ( ( value >= 1 || value === "" ) &&
+					jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
+					style.removeAttribute ) {
+
+				// Setting style.filter to null, "" & " " still leave "filter:" in the cssText
+				// if "filter:" is present at all, clearType is disabled, we want to avoid this
+				// style.removeAttribute is IE Only, but so apparently is this code path...
+				style.removeAttribute( "filter" );
+
+				// if there is no filter style applied in a css rule or unset inline opacity, we are done
+				if ( value === "" || currentStyle && !currentStyle.filter ) {
+					return;
+				}
+			}
+
+			// otherwise, set new filter values
+			style.filter = ralpha.test( filter ) ?
+				filter.replace( ralpha, opacity ) :
+				filter + " " + opacity;
+		}
+	};
+}
+
+// These hooks cannot be added until DOM ready because the support test
+// for it is not run until after DOM ready
+jQuery(function() {
+	if ( !jQuery.support.reliableMarginRight ) {
+		jQuery.cssHooks.marginRight = {
+			get: function( elem, computed ) {
+				if ( computed ) {
+					// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+					// Work around by temporarily setting element display to inline-block
+					return jQuery.swap( elem, { "display": "inline-block" },
+						curCSS, [ elem, "marginRight" ] );
+				}
+			}
+		};
+	}
+
+	// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+	// getComputedStyle returns percent when specified for top/left/bottom/right
+	// rather than make the css module depend on the offset module, we just check for it here
+	if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
+		jQuery.each( [ "top", "left" ], function( i, prop ) {
+			jQuery.cssHooks[ prop ] = {
+				get: function( elem, computed ) {
+					if ( computed ) {
+						computed = curCSS( elem, prop );
+						// if curCSS returns percentage, fallback to offset
+						return rnumnonpx.test( computed ) ?
+							jQuery( elem ).position()[ prop ] + "px" :
+							computed;
+					}
+				}
+			};
+		});
+	}
+
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+	jQuery.expr.filters.hidden = function( elem ) {
+		// Support: Opera <= 12.12
+		// Opera reports offsetWidths and offsetHeights less than zero on some elements
+		return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
+			(!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
+	};
+
+	jQuery.expr.filters.visible = function( elem ) {
+		return !jQuery.expr.filters.hidden( elem );
+	};
+}
+
+// These hooks are used by animate to expand properties
+jQuery.each({
+	margin: "",
+	padding: "",
+	border: "Width"
+}, function( prefix, suffix ) {
+	jQuery.cssHooks[ prefix + suffix ] = {
+		expand: function( value ) {
+			var i = 0,
+				expanded = {},
+
+				// assumes a single number if not a string
+				parts = typeof value === "string" ? value.split(" ") : [ value ];
+
+			for ( ; i < 4; i++ ) {
+				expanded[ prefix + cssExpand[ i ] + suffix ] =
+					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
+			}
+
+			return expanded;
+		}
+	};
+
+	if ( !rmargin.test( prefix ) ) {
+		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
+	}
+});
+var r20 = /%20/g,
+	rbracket = /\[\]$/,
+	rCRLF = /\r?\n/g,
+	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
+	rsubmittable = /^(?:input|select|textarea|keygen)/i;
+
+jQuery.fn.extend({
+	serialize: function() {
+		return jQuery.param( this.serializeArray() );
+	},
+	serializeArray: function() {
+		return this.map(function(){
+			// Can add propHook for "elements" to filter or add form elements
+			var elements = jQuery.prop( this, "elements" );
+			return elements ? jQuery.makeArray( elements ) : this;
+		})
+		.filter(function(){
+			var type = this.type;
+			// Use .is(":disabled") so that fieldset[disabled] works
+			return this.name && !jQuery( this ).is( ":disabled" ) &&
+				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
+				( this.checked || !manipulation_rcheckableType.test( type ) );
+		})
+		.map(function( i, elem ){
+			var val = jQuery( this ).val();
+
+			return val == null ?
+				null :
+				jQuery.isArray( val ) ?
+					jQuery.map( val, function( val ){
+						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+					}) :
+					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+		}).get();
+	}
+});
+
+//Serialize an array of form elements or a set of
+//key/values into a query string
+jQuery.param = function( a, traditional ) {
+	var prefix,
+		s = [],
+		add = function( key, value ) {
+			// If value is a function, invoke it and return its value
+			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
+			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
+		};
+
+	// Set traditional to true for jQuery <= 1.3.2 behavior.
+	if ( traditional === undefined ) {
+		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
+	}
+
+	// If an array was passed in, assume that it is an array of form elements.
+	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+		// Serialize the form elements
+		jQuery.each( a, function() {
+			add( this.name, this.value );
+		});
+
+	} else {
+		// If traditional, encode the "old" way (the way 1.3.2 or older
+		// did it), otherwise encode params recursively.
+		for ( prefix in a ) {
+			buildParams( prefix, a[ prefix ], traditional, add );
+		}
+	}
+
+	// Return the resulting serialization
+	return s.join( "&" ).replace( r20, "+" );
+};
+
+function buildParams( prefix, obj, traditional, add ) {
+	var name;
+
+	if ( jQuery.isArray( obj ) ) {
+		// Serialize array item.
+		jQuery.each( obj, function( i, v ) {
+			if ( traditional || rbracket.test( prefix ) ) {
+				// Treat each array item as a scalar.
+				add( prefix, v );
+
+			} else {
+				// Item is non-scalar (array or object), encode its numeric index.
+				buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
+			}
+		});
+
+	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
+		// Serialize object item.
+		for ( name in obj ) {
+			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+		}
+
+	} else {
+		// Serialize scalar item.
+		add( prefix, obj );
+	}
+}
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+	"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
+
+	// Handle event binding
+	jQuery.fn[ name ] = function( data, fn ) {
+		return arguments.length > 0 ?
+			this.on( name, null, data, fn ) :
+			this.trigger( name );
+	};
+});
+
+jQuery.fn.hover = function( fnOver, fnOut ) {
+	return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+};
+var
+	// Document location
+	ajaxLocParts,
+	ajaxLocation,
+	ajax_nonce = jQuery.now(),
+
+	ajax_rquery = /\?/,
+	rhash = /#.*$/,
+	rts = /([?&])_=[^&]*/,
+	rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
+	// #7653, #8125, #8152: local protocol detection
+	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
+	rnoContent = /^(?:GET|HEAD)$/,
+	rprotocol = /^\/\//,
+	rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
+
+	// Keep a copy of the old load method
+	_load = jQuery.fn.load,
+
+	/* Prefilters
+	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
+	 * 2) These are called:
+	 *    - BEFORE asking for a transport
+	 *    - AFTER param serialization (s.data is a string if s.processData is true)
+	 * 3) key is the dataType
+	 * 4) the catchall symbol "*" can be used
+	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
+	 */
+	prefilters = {},
+
+	/* Transports bindings
+	 * 1) key is the dataType
+	 * 2) the catchall symbol "*" can be used
+	 * 3) selection will start with transport dataType and THEN go to "*" if needed
+	 */
+	transports = {},
+
+	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
+	allTypes = "*/".concat("*");
+
+// #8138, IE may throw an exception when accessing
+// a field from window.location if document.domain has been set
+try {
+	ajaxLocation = location.href;
+} catch( e ) {
+	// Use the href attribute of an A element
+	// since IE will modify it given document.location
+	ajaxLocation = document.createElement( "a" );
+	ajaxLocation.href = "";
+	ajaxLocation = ajaxLocation.href;
+}
+
+// Segment location into parts
+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
+
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+function addToPrefiltersOrTransports( structure ) {
+
+	// dataTypeExpression is optional and defaults to "*"
+	return function( dataTypeExpression, func ) {
+
+		if ( typeof dataTypeExpression !== "string" ) {
+			func = dataTypeExpression;
+			dataTypeExpression = "*";
+		}
+
+		var dataType,
+			i = 0,
+			dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || [];
+
+		if ( jQuery.isFunction( func ) ) {
+			// For each dataType in the dataTypeExpression
+			while ( (dataType = dataTypes[i++]) ) {
+				// Prepend if requested
+				if ( dataType[0] === "+" ) {
+					dataType = dataType.slice( 1 ) || "*";
+					(structure[ dataType ] = structure[ dataType ] || []).unshift( func );
+
+				// Otherwise append
+				} else {
+					(structure[ dataType ] = structure[ dataType ] || []).push( func );
+				}
+			}
+		}
+	};
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
+
+	var inspected = {},
+		seekingTransport = ( structure === transports );
+
+	function inspect( dataType ) {
+		var selected;
+		inspected[ dataType ] = true;
+		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
+			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
+			if( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
+				options.dataTypes.unshift( dataTypeOrTransport );
+				inspect( dataTypeOrTransport );
+				return false;
+			} else if ( seekingTransport ) {
+				return !( selected = dataTypeOrTransport );
+			}
+		});
+		return selected;
+	}
+
+	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
+}
+
+// A special extend for ajax options
+// that takes "flat" options (not to be deep extended)
+// Fixes #9887
+function ajaxExtend( target, src ) {
+	var deep, key,
+		flatOptions = jQuery.ajaxSettings.flatOptions || {};
+
+	for ( key in src ) {
+		if ( src[ key ] !== undefined ) {
+			( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
+		}
+	}
+	if ( deep ) {
+		jQuery.extend( true, target, deep );
+	}
+
+	return target;
+}
+
+jQuery.fn.load = function( url, params, callback ) {
+	if ( typeof url !== "string" && _load ) {
+		return _load.apply( this, arguments );
+	}
+
+	var selector, response, type,
+		self = this,
+		off = url.indexOf(" ");
+
+	if ( off >= 0 ) {
+		selector = url.slice( off, url.length );
+		url = url.slice( 0, off );
+	}
+
+	// If it's a function
+	if ( jQuery.isFunction( params ) ) {
+
+		// We assume that it's the callback
+		callback = params;
+		params = undefined;
+
+	// Otherwise, build a param string
+	} else if ( params && typeof params === "object" ) {
+		type = "POST";
+	}
+
+	// If we have elements to modify, make the request
+	if ( self.length > 0 ) {
+		jQuery.ajax({
+			url: url,
+
+			// if "type" variable is undefined, then "GET" method will be used
+			type: type,
+			dataType: "html",
+			data: params
+		}).done(function( responseText ) {
+
+			// Save response for use in complete callback
+			response = arguments;
+
+			self.html( selector ?
+
+				// If a selector was specified, locate the right elements in a dummy div
+				// Exclude scripts to avoid IE 'Permission Denied' errors
+				jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
+
+				// Otherwise use the full result
+				responseText );
+
+		}).complete( callback && function( jqXHR, status ) {
+			self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
+		});
+	}
+
+	return this;
+};
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){
+	jQuery.fn[ type ] = function( fn ){
+		return this.on( type, fn );
+	};
+});
+
+jQuery.each( [ "get", "post" ], function( i, method ) {
+	jQuery[ method ] = function( url, data, callback, type ) {
+		// shift arguments if data argument was omitted
+		if ( jQuery.isFunction( data ) ) {
+			type = type || callback;
+			callback = data;
+			data = undefined;
+		}
+
+		return jQuery.ajax({
+			url: url,
+			type: method,
+			dataType: type,
+			data: data,
+			success: callback
+		});
+	};
+});
+
+jQuery.extend({
+
+	// Counter for holding the number of active queries
+	active: 0,
+
+	// Last-Modified header cache for next request
+	lastModified: {},
+	etag: {},
+
+	ajaxSettings: {
+		url: ajaxLocation,
+		type: "GET",
+		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
+		global: true,
+		processData: true,
+		async: true,
+		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+		/*
+		timeout: 0,
+		data: null,
+		dataType: null,
+		username: null,
+		password: null,
+		cache: null,
+		throws: false,
+		traditional: false,
+		headers: {},
+		*/
+
+		accepts: {
+			"*": allTypes,
+			text: "text/plain",
+			html: "text/html",
+			xml: "application/xml, text/xml",
+			json: "application/json, text/javascript"
+		},
+
+		contents: {
+			xml: /xml/,
+			html: /html/,
+			json: /json/
+		},
+
+		responseFields: {
+			xml: "responseXML",
+			text: "responseText"
+		},
+
+		// Data converters
+		// Keys separate source (or catchall "*") and destination types with a single space
+		converters: {
+
+			// Convert anything to text
+			"* text": window.String,
+
+			// Text to html (true = no transformation)
+			"text html": true,
+
+			// Evaluate text as a json expression
+			"text json": jQuery.parseJSON,
+
+			// Parse text as xml
+			"text xml": jQuery.parseXML
+		},
+
+		// For options that shouldn't be deep extended:
+		// you can add your own custom options here if
+		// and when you create one that shouldn't be
+		// deep extended (see ajaxExtend)
+		flatOptions: {
+			url: true,
+			context: true
+		}
+	},
+
+	// Creates a full fledged settings object into target
+	// with both ajaxSettings and settings fields.
+	// If target is omitted, writes into ajaxSettings.
+	ajaxSetup: function( target, settings ) {
+		return settings ?
+
+			// Building a settings object
+			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
+
+			// Extending ajaxSettings
+			ajaxExtend( jQuery.ajaxSettings, target );
+	},
+
+	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+	ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+	// Main method
+	ajax: function( url, options ) {
+
+		// If url is an object, simulate pre-1.5 signature
+		if ( typeof url === "object" ) {
+			options = url;
+			url = undefined;
+		}
+
+		// Force options to be an object
+		options = options || {};
+
+		var // Cross-domain detection vars
+			parts,
+			// Loop variable
+			i,
+			// URL without anti-cache param
+			cacheURL,
+			// Response headers as string
+			responseHeadersString,
+			// timeout handle
+			timeoutTimer,
+
+			// To know if global events are to be dispatched
+			fireGlobals,
+
+			transport,
+			// Response headers
+			responseHeaders,
+			// Create the final options object
+			s = jQuery.ajaxSetup( {}, options ),
+			// Callbacks context
+			callbackContext = s.context || s,
+			// Context for global events is callbackContext if it is a DOM node or jQuery collection
+			globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
+				jQuery( callbackContext ) :
+				jQuery.event,
+			// Deferreds
+			deferred = jQuery.Deferred(),
+			completeDeferred = jQuery.Callbacks("once memory"),
+			// Status-dependent callbacks
+			statusCode = s.statusCode || {},
+			// Headers (they are sent all at once)
+			requestHeaders = {},
+			requestHeadersNames = {},
+			// The jqXHR state
+			state = 0,
+			// Default abort message
+			strAbort = "canceled",
+			// Fake xhr
+			jqXHR = {
+				readyState: 0,
+
+				// Builds headers hashtable if needed
+				getResponseHeader: function( key ) {
+					var match;
+					if ( state === 2 ) {
+						if ( !responseHeaders ) {
+							responseHeaders = {};
+							while ( (match = rheaders.exec( responseHeadersString )) ) {
+								responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
+							}
+						}
+						match = responseHeaders[ key.toLowerCase() ];
+					}
+					return match == null ? null : match;
+				},
+
+				// Raw string
+				getAllResponseHeaders: function() {
+					return state === 2 ? responseHeadersString : null;
+				},
+
+				// Caches the header
+				setRequestHeader: function( name, value ) {
+					var lname = name.toLowerCase();
+					if ( !state ) {
+						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+						requestHeaders[ name ] = value;
+					}
+					return this;
+				},
+
+				// Overrides response content-type header
+				overrideMimeType: function( type ) {
+					if ( !state ) {
+						s.mimeType = type;
+					}
+					return this;
+				},
+
+				// Status-dependent callbacks
+				statusCode: function( map ) {
+					var code;
+					if ( map ) {
+						if ( state < 2 ) {
+							for ( code in map ) {
+								// Lazy-add the new callback in a way that preserves old ones
+								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
+							}
+						} else {
+							// Execute the appropriate callbacks
+							jqXHR.always( map[ jqXHR.status ] );
+						}
+					}
+					return this;
+				},
+
+				// Cancel the request
+				abort: function( statusText ) {
+					var finalText = statusText || strAbort;
+					if ( transport ) {
+						transport.abort( finalText );
+					}
+					done( 0, finalText );
+					return this;
+				}
+			};
+
+		// Attach deferreds
+		deferred.promise( jqXHR ).complete = completeDeferred.add;
+		jqXHR.success = jqXHR.done;
+		jqXHR.error = jqXHR.fail;
+
+		// Remove hash character (#7531: and string promotion)
+		// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
+		// Handle falsy url in the settings object (#10093: consistency with old signature)
+		// We also use the url parameter if available
+		s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
+
+		// Alias method option to type as per ticket #12004
+		s.type = options.method || options.type || s.method || s.type;
+
+		// Extract dataTypes list
+		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( core_rnotwhite ) || [""];
+
+		// A cross-domain request is in order when we have a protocol:host:port mismatch
+		if ( s.crossDomain == null ) {
+			parts = rurl.exec( s.url.toLowerCase() );
+			s.crossDomain = !!( parts &&
+				( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
+					( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
+						( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
+			);
+		}
+
+		// Convert data if not already a string
+		if ( s.data && s.processData && typeof s.data !== "string" ) {
+			s.data = jQuery.param( s.data, s.traditional );
+		}
+
+		// Apply prefilters
+		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+		// If request was aborted inside a prefilter, stop there
+		if ( state === 2 ) {
+			return jqXHR;
+		}
+
+		// We can fire global events as of now if asked to
+		fireGlobals = s.global;
+
+		// Watch for a new set of requests
+		if ( fireGlobals && jQuery.active++ === 0 ) {
+			jQuery.event.trigger("ajaxStart");
+		}
+
+		// Uppercase the type
+		s.type = s.type.toUpperCase();
+
+		// Determine if request has content
+		s.hasContent = !rnoContent.test( s.type );
+
+		// Save the URL in case we're toying with the If-Modified-Since
+		// and/or If-None-Match header later on
+		cacheURL = s.url;
+
+		// More options handling for requests with no content
+		if ( !s.hasContent ) {
+
+			// If data is available, append data to url
+			if ( s.data ) {
+				cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
+				// #9682: remove data so that it's not used in an eventual retry
+				delete s.data;
+			}
+
+			// Add anti-cache in url if needed
+			if ( s.cache === false ) {
+				s.url = rts.test( cacheURL ) ?
+
+					// If there is already a '_' parameter, set its value
+					cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) :
+
+					// Otherwise add one to the end
+					cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++;
+			}
+		}
+
+		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+		if ( s.ifModified ) {
+			if ( jQuery.lastModified[ cacheURL ] ) {
+				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
+			}
+			if ( jQuery.etag[ cacheURL ] ) {
+				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
+			}
+		}
+
+		// Set the correct header, if data is being sent
+		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+			jqXHR.setRequestHeader( "Content-Type", s.contentType );
+		}
+
+		// Set the Accepts header for the server, depending on the dataType
+		jqXHR.setRequestHeader(
+			"Accept",
+			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
+				s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
+				s.accepts[ "*" ]
+		);
+
+		// Check for headers option
+		for ( i in s.headers ) {
+			jqXHR.setRequestHeader( i, s.headers[ i ] );
+		}
+
+		// Allow custom headers/mimetypes and early abort
+		if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
+			// Abort if not done already and return
+			return jqXHR.abort();
+		}
+
+		// aborting is no longer a cancellation
+		strAbort = "abort";
+
+		// Install callbacks on deferreds
+		for ( i in { success: 1, error: 1, complete: 1 } ) {
+			jqXHR[ i ]( s[ i ] );
+		}
+
+		// Get transport
+		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+		// If no transport, we auto-abort
+		if ( !transport ) {
+			done( -1, "No Transport" );
+		} else {
+			jqXHR.readyState = 1;
+
+			// Send global event
+			if ( fireGlobals ) {
+				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+			}
+			// Timeout
+			if ( s.async && s.timeout > 0 ) {
+				timeoutTimer = setTimeout(function() {
+					jqXHR.abort("timeout");
+				}, s.timeout );
+			}
+
+			try {
+				state = 1;
+				transport.send( requestHeaders, done );
+			} catch ( e ) {
+				// Propagate exception as error if not done
+				if ( state < 2 ) {
+					done( -1, e );
+				// Simply rethrow otherwise
+				} else {
+					throw e;
+				}
+			}
+		}
+
+		// Callback for when everything is done
+		function done( status, nativeStatusText, responses, headers ) {
+			var isSuccess, success, error, response, modified,
+				statusText = nativeStatusText;
+
+			// Called once
+			if ( state === 2 ) {
+				return;
+			}
+
+			// State is "done" now
+			state = 2;
+
+			// Clear timeout if it exists
+			if ( timeoutTimer ) {
+				clearTimeout( timeoutTimer );
+			}
+
+			// Dereference transport for early garbage collection
+			// (no matter how long the jqXHR object will be used)
+			transport = undefined;
+
+			// Cache response headers
+			responseHeadersString = headers || "";
+
+			// Set readyState
+			jqXHR.readyState = status > 0 ? 4 : 0;
+
+			// Get response data
+			if ( responses ) {
+				response = ajaxHandleResponses( s, jqXHR, responses );
+			}
+
+			// If successful, handle type chaining
+			if ( status >= 200 && status < 300 || status === 304 ) {
+
+				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+				if ( s.ifModified ) {
+					modified = jqXHR.getResponseHeader("Last-Modified");
+					if ( modified ) {
+						jQuery.lastModified[ cacheURL ] = modified;
+					}
+					modified = jqXHR.getResponseHeader("etag");
+					if ( modified ) {
+						jQuery.etag[ cacheURL ] = modified;
+					}
+				}
+
+				// if no content
+				if ( status === 204 ) {
+					isSuccess = true;
+					statusText = "nocontent";
+
+				// if not modified
+				} else if ( status === 304 ) {
+					isSuccess = true;
+					statusText = "notmodified";
+
+				// If we have data, let's convert it
+				} else {
+					isSuccess = ajaxConvert( s, response );
+					statusText = isSuccess.state;
+					success = isSuccess.data;
+					error = isSuccess.error;
+					isSuccess = !error;
+				}
+			} else {
+				// We extract error from statusText
+				// then normalize statusText and status for non-aborts
+				error = statusText;
+				if ( status || !statusText ) {
+					statusText = "error";
+					if ( status < 0 ) {
+						status = 0;
+					}
+				}
+			}
+
+			// Set data for the fake xhr object
+			jqXHR.status = status;
+			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
+
+			// Success/Error
+			if ( isSuccess ) {
+				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+			} else {
+				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+			}
+
+			// Status-dependent callbacks
+			jqXHR.statusCode( statusCode );
+			statusCode = undefined;
+
+			if ( fireGlobals ) {
+				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
+					[ jqXHR, s, isSuccess ? success : error ] );
+			}
+
+			// Complete
+			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
+
+			if ( fireGlobals ) {
+				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
+				// Handle the global AJAX counter
+				if ( !( --jQuery.active ) ) {
+					jQuery.event.trigger("ajaxStop");
+				}
+			}
+		}
+
+		return jqXHR;
+	},
+
+	getScript: function( url, callback ) {
+		return jQuery.get( url, undefined, callback, "script" );
+	},
+
+	getJSON: function( url, data, callback ) {
+		return jQuery.get( url, data, callback, "json" );
+	}
+});
+
+/* Handles responses to an ajax request:
+ * - sets all responseXXX fields accordingly
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+	var firstDataType, ct, finalDataType, type,
+		contents = s.contents,
+		dataTypes = s.dataTypes,
+		responseFields = s.responseFields;
+
+	// Fill responseXXX fields
+	for ( type in responseFields ) {
+		if ( type in responses ) {
+			jqXHR[ responseFields[type] ] = responses[ type ];
+		}
+	}
+
+	// Remove auto dataType and get content-type in the process
+	while( dataTypes[ 0 ] === "*" ) {
+		dataTypes.shift();
+		if ( ct === undefined ) {
+			ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
+		}
+	}
+
+	// Check if we're dealing with a known content-type
+	if ( ct ) {
+		for ( type in contents ) {
+			if ( contents[ type ] && contents[ type ].test( ct ) ) {
+				dataTypes.unshift( type );
+				break;
+			}
+		}
+	}
+
+	// Check to see if we have a response for the expected dataType
+	if ( dataTypes[ 0 ] in responses ) {
+		finalDataType = dataTypes[ 0 ];
+	} else {
+		// Try convertible dataTypes
+		for ( type in responses ) {
+			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
+				finalDataType = type;
+				break;
+			}
+			if ( !firstDataType ) {
+				firstDataType = type;
+			}
+		}
+		// Or just use first one
+		finalDataType = finalDataType || firstDataType;
+	}
+
+	// If we found a dataType
+	// We add the dataType to the list if needed
+	// and return the corresponding response
+	if ( finalDataType ) {
+		if ( finalDataType !== dataTypes[ 0 ] ) {
+			dataTypes.unshift( finalDataType );
+		}
+		return responses[ finalDataType ];
+	}
+}
+
+// Chain conversions given the request and the original response
+function ajaxConvert( s, response ) {
+	var conv2, current, conv, tmp,
+		converters = {},
+		i = 0,
+		// Work with a copy of dataTypes in case we need to modify it for conversion
+		dataTypes = s.dataTypes.slice(),
+		prev = dataTypes[ 0 ];
+
+	// Apply the dataFilter if provided
+	if ( s.dataFilter ) {
+		response = s.dataFilter( response, s.dataType );
+	}
+
+	// Create converters map with lowercased keys
+	if ( dataTypes[ 1 ] ) {
+		for ( conv in s.converters ) {
+			converters[ conv.toLowerCase() ] = s.converters[ conv ];
+		}
+	}
+
+	// Convert to each sequential dataType, tolerating list modification
+	for ( ; (current = dataTypes[++i]); ) {
+
+		// There's only work to do if current dataType is non-auto
+		if ( current !== "*" ) {
+
+			// Convert response if prev dataType is non-auto and differs from current
+			if ( prev !== "*" && prev !== current ) {
+
+				// Seek a direct converter
+				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
+
+				// If none found, seek a pair
+				if ( !conv ) {
+					for ( conv2 in converters ) {
+
+						// If conv2 outputs current
+						tmp = conv2.split(" ");
+						if ( tmp[ 1 ] === current ) {
+
+							// If prev can be converted to accepted input
+							conv = converters[ prev + " " + tmp[ 0 ] ] ||
+								converters[ "* " + tmp[ 0 ] ];
+							if ( conv ) {
+								// Condense equivalence converters
+								if ( conv === true ) {
+									conv = converters[ conv2 ];
+
+								// Otherwise, insert the intermediate dataType
+								} else if ( converters[ conv2 ] !== true ) {
+									current = tmp[ 0 ];
+									dataTypes.splice( i--, 0, current );
+								}
+
+								break;
+							}
+						}
+					}
+				}
+
+				// Apply converter (if not an equivalence)
+				if ( conv !== true ) {
+
+					// Unless errors are allowed to bubble, catch and return them
+					if ( conv && s["throws"] ) {
+						response = conv( response );
+					} else {
+						try {
+							response = conv( response );
+						} catch ( e ) {
+							return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
+						}
+					}
+				}
+			}
+
+			// Update prev for next iteration
+			prev = current;
+		}
+	}
+
+	return { state: "success", data: response };
+}
+// Install script dataType
+jQuery.ajaxSetup({
+	accepts: {
+		script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
+	},
+	contents: {
+		script: /(?:java|ecma)script/
+	},
+	converters: {
+		"text script": function( text ) {
+			jQuery.globalEval( text );
+			return text;
+		}
+	}
+});
+
+// Handle cache's special case and global
+jQuery.ajaxPrefilter( "script", function( s ) {
+	if ( s.cache === undefined ) {
+		s.cache = false;
+	}
+	if ( s.crossDomain ) {
+		s.type = "GET";
+		s.global = false;
+	}
+});
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function(s) {
+
+	// This transport only deals with cross domain requests
+	if ( s.crossDomain ) {
+
+		var script,
+			head = document.head || jQuery("head")[0] || document.documentElement;
+
+		return {
+
+			send: function( _, callback ) {
+
+				script = document.createElement("script");
+
+				script.async = true;
+
+				if ( s.scriptCharset ) {
+					script.charset = s.scriptCharset;
+				}
+
+				script.src = s.url;
+
+				// Attach handlers for all browsers
+				script.onload = script.onreadystatechange = function( _, isAbort ) {
+
+					if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
+
+						// Handle memory leak in IE
+						script.onload = script.onreadystatechange = null;
+
+						// Remove the script
+						if ( script.parentNode ) {
+							script.parentNode.removeChild( script );
+						}
+
+						// Dereference the script
+						script = null;
+
+						// Callback if not abort
+						if ( !isAbort ) {
+							callback( 200, "success" );
+						}
+					}
+				};
+
+				// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
+				// Use native DOM manipulation to avoid our domManip AJAX trickery
+				head.insertBefore( script, head.firstChild );
+			},
+
+			abort: function() {
+				if ( script ) {
+					script.onload( undefined, true );
+				}
+			}
+		};
+	}
+});
+var oldCallbacks = [],
+	rjsonp = /(=)\?(?=&|$)|\?\?/;
+
+// Default jsonp settings
+jQuery.ajaxSetup({
+	jsonp: "callback",
+	jsonpCallback: function() {
+		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_nonce++ ) );
+		this[ callback ] = true;
+		return callback;
+	}
+});
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+	var callbackName, overwritten, responseContainer,
+		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
+			"url" :
+			typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
+		);
+
+	// Handle iff the expected data type is "jsonp" or we have a parameter to set
+	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
+
+		// Get callback name, remembering preexisting value associated with it
+		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
+			s.jsonpCallback() :
+			s.jsonpCallback;
+
+		// Insert callback into url or form data
+		if ( jsonProp ) {
+			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
+		} else if ( s.jsonp !== false ) {
+			s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
+		}
+
+		// Use data converter to retrieve json after script execution
+		s.converters["script json"] = function() {
+			if ( !responseContainer ) {
+				jQuery.error( callbackName + " was not called" );
+			}
+			return responseContainer[ 0 ];
+		};
+
+		// force json dataType
+		s.dataTypes[ 0 ] = "json";
+
+		// Install callback
+		overwritten = window[ callbackName ];
+		window[ callbackName ] = function() {
+			responseContainer = arguments;
+		};
+
+		// Clean-up function (fires after converters)
+		jqXHR.always(function() {
+			// Restore preexisting value
+			window[ callbackName ] = overwritten;
+
+			// Save back as free
+			if ( s[ callbackName ] ) {
+				// make sure that re-using the options doesn't screw things around
+				s.jsonpCallback = originalSettings.jsonpCallback;
+
+				// save the callback name for future use
+				oldCallbacks.push( callbackName );
+			}
+
+			// Call if it was a function and we have a response
+			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
+				overwritten( responseContainer[ 0 ] );
+			}
+
+			responseContainer = overwritten = undefined;
+		});
+
+		// Delegate to script
+		return "script";
+	}
+});
+var xhrCallbacks, xhrSupported,
+	xhrId = 0,
+	// #5280: Internet Explorer will keep connections alive if we don't abort on unload
+	xhrOnUnloadAbort = window.ActiveXObject && function() {
+		// Abort all pending requests
+		var key;
+		for ( key in xhrCallbacks ) {
+			xhrCallbacks[ key ]( undefined, true );
+		}
+	};
+
+// Functions to create xhrs
+function createStandardXHR() {
+	try {
+		return new window.XMLHttpRequest();
+	} catch( e ) {}
+}
+
+function createActiveXHR() {
+	try {
+		return new window.ActiveXObject("Microsoft.XMLHTTP");
+	} catch( e ) {}
+}
+
+// Create the request object
+// (This is still attached to ajaxSettings for backward compatibility)
+jQuery.ajaxSettings.xhr = window.ActiveXObject ?
+	/* Microsoft failed to properly
+	 * implement the XMLHttpRequest in IE7 (can't request local files),
+	 * so we use the ActiveXObject when it is available
+	 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+	 * we need a fallback.
+	 */
+	function() {
+		return !this.isLocal && createStandardXHR() || createActiveXHR();
+	} :
+	// For all other browsers, use the standard XMLHttpRequest object
+	createStandardXHR;
+
+// Determine support properties
+xhrSupported = jQuery.ajaxSettings.xhr();
+jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
+xhrSupported = jQuery.support.ajax = !!xhrSupported;
+
+// Create transport if the browser can provide an xhr
+if ( xhrSupported ) {
+
+	jQuery.ajaxTransport(function( s ) {
+		// Cross domain only allowed if supported through XMLHttpRequest
+		if ( !s.crossDomain || jQuery.support.cors ) {
+
+			var callback;
+
+			return {
+				send: function( headers, complete ) {
+
+					// Get a new xhr
+					var handle, i,
+						xhr = s.xhr();
+
+					// Open the socket
+					// Passing null username, generates a login popup on Opera (#2865)
+					if ( s.username ) {
+						xhr.open( s.type, s.url, s.async, s.username, s.password );
+					} else {
+						xhr.open( s.type, s.url, s.async );
+					}
+
+					// Apply custom fields if provided
+					if ( s.xhrFields ) {
+						for ( i in s.xhrFields ) {
+							xhr[ i ] = s.xhrFields[ i ];
+						}
+					}
+
+					// Override mime type if needed
+					if ( s.mimeType && xhr.overrideMimeType ) {
+						xhr.overrideMimeType( s.mimeType );
+					}
+
+					// X-Requested-With header
+					// For cross-domain requests, seeing as conditions for a preflight are
+					// akin to a jigsaw puzzle, we simply never set it to be sure.
+					// (it can always be set on a per-request basis or even using ajaxSetup)
+					// For same-domain requests, won't change header if already provided.
+					if ( !s.crossDomain && !headers["X-Requested-With"] ) {
+						headers["X-Requested-With"] = "XMLHttpRequest";
+					}
+
+					// Need an extra try/catch for cross domain requests in Firefox 3
+					try {
+						for ( i in headers ) {
+							xhr.setRequestHeader( i, headers[ i ] );
+						}
+					} catch( err ) {}
+
+					// Do send the request
+					// This may raise an exception which is actually
+					// handled in jQuery.ajax (so no try/catch here)
+					xhr.send( ( s.hasContent && s.data ) || null );
+
+					// Listener
+					callback = function( _, isAbort ) {
+						var status, responseHeaders, statusText, responses;
+
+						// Firefox throws exceptions when accessing properties
+						// of an xhr when a network error occurred
+						// http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
+						try {
+
+							// Was never called and is aborted or complete
+							if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+
+								// Only called once
+								callback = undefined;
+
+								// Do not keep as active anymore
+								if ( handle ) {
+									xhr.onreadystatechange = jQuery.noop;
+									if ( xhrOnUnloadAbort ) {
+										delete xhrCallbacks[ handle ];
+									}
+								}
+
+								// If it's an abort
+								if ( isAbort ) {
+									// Abort it manually if needed
+									if ( xhr.readyState !== 4 ) {
+										xhr.abort();
+									}
+								} else {
+									responses = {};
+									status = xhr.status;
+									responseHeaders = xhr.getAllResponseHeaders();
+
+									// When requesting binary data, IE6-9 will throw an exception
+									// on any attempt to access responseText (#11426)
+									if ( typeof xhr.responseText === "string" ) {
+										responses.text = xhr.responseText;
+									}
+
+									// Firefox throws an exception when accessing
+									// statusText for faulty cross-domain requests
+									try {
+										statusText = xhr.statusText;
+									} catch( e ) {
+										// We normalize with Webkit giving an empty statusText
+										statusText = "";
+									}
+
+									// Filter status for non standard behaviors
+
+									// If the request is local and we have data: assume a success
+									// (success with no data won't get notified, that's the best we
+									// can do given current implementations)
+									if ( !status && s.isLocal && !s.crossDomain ) {
+										status = responses.text ? 200 : 404;
+									// IE - #1450: sometimes returns 1223 when it should be 204
+									} else if ( status === 1223 ) {
+										status = 204;
+									}
+								}
+							}
+						} catch( firefoxAccessException ) {
+							if ( !isAbort ) {
+								complete( -1, firefoxAccessException );
+							}
+						}
+
+						// Call complete if needed
+						if ( responses ) {
+							complete( status, statusText, responses, responseHeaders );
+						}
+					};
+
+					if ( !s.async ) {
+						// if we're in sync mode we fire the callback
+						callback();
+					} else if ( xhr.readyState === 4 ) {
+						// (IE6 & IE7) if it's in cache and has been
+						// retrieved directly we need to fire the callback
+						setTimeout( callback );
+					} else {
+						handle = ++xhrId;
+						if ( xhrOnUnloadAbort ) {
+							// Create the active xhrs callbacks list if needed
+							// and attach the unload handler
+							if ( !xhrCallbacks ) {
+								xhrCallbacks = {};
+								jQuery( window ).unload( xhrOnUnloadAbort );
+							}
+							// Add to list of active xhrs callbacks
+							xhrCallbacks[ handle ] = callback;
+						}
+						xhr.onreadystatechange = callback;
+					}
+				},
+
+				abort: function() {
+					if ( callback ) {
+						callback( undefined, true );
+					}
+				}
+			};
+		}
+	});
+}
+var fxNow, timerId,
+	rfxtypes = /^(?:toggle|show|hide)$/,
+	rfxnum = new RegExp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
+	rrun = /queueHooks$/,
+	animationPrefilters = [ defaultPrefilter ],
+	tweeners = {
+		"*": [function( prop, value ) {
+			var end, unit,
+				tween = this.createTween( prop, value ),
+				parts = rfxnum.exec( value ),
+				target = tween.cur(),
+				start = +target || 0,
+				scale = 1,
+				maxIterations = 20;
+
+			if ( parts ) {
+				end = +parts[2];
+				unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" );
+
+				// We need to compute starting value
+				if ( unit !== "px" && start ) {
+					// Iteratively approximate from a nonzero starting point
+					// Prefer the current property, because this process will be trivial if it uses the same units
+					// Fallback to end or a simple constant
+					start = jQuery.css( tween.elem, prop, true ) || end || 1;
+
+					do {
+						// If previous iteration zeroed out, double until we get *something*
+						// Use a string for doubling factor so we don't accidentally see scale as unchanged below
+						scale = scale || ".5";
+
+						// Adjust and apply
+						start = start / scale;
+						jQuery.style( tween.elem, prop, start + unit );
+
+					// Update scale, tolerating zero or NaN from tween.cur()
+					// And breaking the loop if scale is unchanged or perfect, or if we've just had enough
+					} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
+				}
+
+				tween.unit = unit;
+				tween.start = start;
+				// If a +=/-= token was provided, we're doing a relative animation
+				tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end;
+			}
+			return tween;
+		}]
+	};
+
+// Animations created synchronously will run synchronously
+function createFxNow() {
+	setTimeout(function() {
+		fxNow = undefined;
+	});
+	return ( fxNow = jQuery.now() );
+}
+
+function createTweens( animation, props ) {
+	jQuery.each( props, function( prop, value ) {
+		var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
+			index = 0,
+			length = collection.length;
+		for ( ; index < length; index++ ) {
+			if ( collection[ index ].call( animation, prop, value ) ) {
+
+				// we're done with this property
+				return;
+			}
+		}
+	});
+}
+
+function Animation( elem, properties, options ) {
+	var result,
+		stopped,
+		index = 0,
+		length = animationPrefilters.length,
+		deferred = jQuery.Deferred().always( function() {
+			// don't match elem in the :animated selector
+			delete tick.elem;
+		}),
+		tick = function() {
+			if ( stopped ) {
+				return false;
+			}
+			var currentTime = fxNow || createFxNow(),
+				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
+				// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
+				temp = remaining / animation.duration || 0,
+				percent = 1 - temp,
+				index = 0,
+				length = animation.tweens.length;
+
+			for ( ; index < length ; index++ ) {
+				animation.tweens[ index ].run( percent );
+			}
+
+			deferred.notifyWith( elem, [ animation, percent, remaining ]);
+
+			if ( percent < 1 && length ) {
+				return remaining;
+			} else {
+				deferred.resolveWith( elem, [ animation ] );
+				return false;
+			}
+		},
+		animation = deferred.promise({
+			elem: elem,
+			props: jQuery.extend( {}, properties ),
+			opts: jQuery.extend( true, { specialEasing: {} }, options ),
+			originalProperties: properties,
+			originalOptions: options,
+			startTime: fxNow || createFxNow(),
+			duration: options.duration,
+			tweens: [],
+			createTween: function( prop, end ) {
+				var tween = jQuery.Tween( elem, animation.opts, prop, end,
+						animation.opts.specialEasing[ prop ] || animation.opts.easing );
+				animation.tweens.push( tween );
+				return tween;
+			},
+			stop: function( gotoEnd ) {
+				var index = 0,
+					// if we are going to the end, we want to run all the tweens
+					// otherwise we skip this part
+					length = gotoEnd ? animation.tweens.length : 0;
+				if ( stopped ) {
+					return this;
+				}
+				stopped = true;
+				for ( ; index < length ; index++ ) {
+					animation.tweens[ index ].run( 1 );
+				}
+
+				// resolve when we played the last frame
+				// otherwise, reject
+				if ( gotoEnd ) {
+					deferred.resolveWith( elem, [ animation, gotoEnd ] );
+				} else {
+					deferred.rejectWith( elem, [ animation, gotoEnd ] );
+				}
+				return this;
+			}
+		}),
+		props = animation.props;
+
+	propFilter( props, animation.opts.specialEasing );
+
+	for ( ; index < length ; index++ ) {
+		result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
+		if ( result ) {
+			return result;
+		}
+	}
+
+	createTweens( animation, props );
+
+	if ( jQuery.isFunction( animation.opts.start ) ) {
+		animation.opts.start.call( elem, animation );
+	}
+
+	jQuery.fx.timer(
+		jQuery.extend( tick, {
+			elem: elem,
+			anim: animation,
+			queue: animation.opts.queue
+		})
+	);
+
+	// attach callbacks from options
+	return animation.progress( animation.opts.progress )
+		.done( animation.opts.done, animation.opts.complete )
+		.fail( animation.opts.fail )
+		.always( animation.opts.always );
+}
+
+function propFilter( props, specialEasing ) {
+	var value, name, index, easing, hooks;
+
+	// camelCase, specialEasing and expand cssHook pass
+	for ( index in props ) {
+		name = jQuery.camelCase( index );
+		easing = specialEasing[ name ];
+		value = props[ index ];
+		if ( jQuery.isArray( value ) ) {
+			easing = value[ 1 ];
+			value = props[ index ] = value[ 0 ];
+		}
+
+		if ( index !== name ) {
+			props[ name ] = value;
+			delete props[ index ];
+		}
+
+		hooks = jQuery.cssHooks[ name ];
+		if ( hooks && "expand" in hooks ) {
+			value = hooks.expand( value );
+			delete props[ name ];
+
+			// not quite $.extend, this wont overwrite keys already present.
+			// also - reusing 'index' from above because we have the correct "name"
+			for ( index in value ) {
+				if ( !( index in props ) ) {
+					props[ index ] = value[ index ];
+					specialEasing[ index ] = easing;
+				}
+			}
+		} else {
+			specialEasing[ name ] = easing;
+		}
+	}
+}
+
+jQuery.Animation = jQuery.extend( Animation, {
+
+	tweener: function( props, callback ) {
+		if ( jQuery.isFunction( props ) ) {
+			callback = props;
+			props = [ "*" ];
+		} else {
+			props = props.split(" ");
+		}
+
+		var prop,
+			index = 0,
+			length = props.length;
+
+		for ( ; index < length ; index++ ) {
+			prop = props[ index ];
+			tweeners[ prop ] = tweeners[ prop ] || [];
+			tweeners[ prop ].unshift( callback );
+		}
+	},
+
+	prefilter: function( callback, prepend ) {
+		if ( prepend ) {
+			animationPrefilters.unshift( callback );
+		} else {
+			animationPrefilters.push( callback );
+		}
+	}
+});
+
+function defaultPrefilter( elem, props, opts ) {
+	/*jshint validthis:true */
+	var prop, index, length,
+		value, dataShow, toggle,
+		tween, hooks, oldfire,
+		anim = this,
+		style = elem.style,
+		orig = {},
+		handled = [],
+		hidden = elem.nodeType && isHidden( elem );
+
+	// handle queue: false promises
+	if ( !opts.queue ) {
+		hooks = jQuery._queueHooks( elem, "fx" );
+		if ( hooks.unqueued == null ) {
+			hooks.unqueued = 0;
+			oldfire = hooks.empty.fire;
+			hooks.empty.fire = function() {
+				if ( !hooks.unqueued ) {
+					oldfire();
+				}
+			};
+		}
+		hooks.unqueued++;
+
+		anim.always(function() {
+			// doing this makes sure that the complete handler will be called
+			// before this completes
+			anim.always(function() {
+				hooks.unqueued--;
+				if ( !jQuery.queue( elem, "fx" ).length ) {
+					hooks.empty.fire();
+				}
+			});
+		});
+	}
+
+	// height/width overflow pass
+	if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
+		// Make sure that nothing sneaks out
+		// Record all 3 overflow attributes because IE does not
+		// change the overflow attribute when overflowX and
+		// overflowY are set to the same value
+		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
+
+		// Set display property to inline-block for height/width
+		// animations on inline elements that are having width/height animated
+		if ( jQuery.css( elem, "display" ) === "inline" &&
+				jQuery.css( elem, "float" ) === "none" ) {
+
+			// inline-level elements accept inline-block;
+			// block-level elements need to be inline with layout
+			if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) {
+				style.display = "inline-block";
+
+			} else {
+				style.zoom = 1;
+			}
+		}
+	}
+
+	if ( opts.overflow ) {
+		style.overflow = "hidden";
+		if ( !jQuery.support.shrinkWrapBlocks ) {
+			anim.always(function() {
+				style.overflow = opts.overflow[ 0 ];
+				style.overflowX = opts.overflow[ 1 ];
+				style.overflowY = opts.overflow[ 2 ];
+			});
+		}
+	}
+
+
+	// show/hide pass
+	for ( index in props ) {
+		value = props[ index ];
+		if ( rfxtypes.exec( value ) ) {
+			delete props[ index ];
+			toggle = toggle || value === "toggle";
+			if ( value === ( hidden ? "hide" : "show" ) ) {
+				continue;
+			}
+			handled.push( index );
+		}
+	}
+
+	length = handled.length;
+	if ( length ) {
+		dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} );
+		if ( "hidden" in dataShow ) {
+			hidden = dataShow.hidden;
+		}
+
+		// store state if its toggle - enables .stop().toggle() to "reverse"
+		if ( toggle ) {
+			dataShow.hidden = !hidden;
+		}
+		if ( hidden ) {
+			jQuery( elem ).show();
+		} else {
+			anim.done(function() {
+				jQuery( elem ).hide();
+			});
+		}
+		anim.done(function() {
+			var prop;
+			jQuery._removeData( elem, "fxshow" );
+			for ( prop in orig ) {
+				jQuery.style( elem, prop, orig[ prop ] );
+			}
+		});
+		for ( index = 0 ; index < length ; index++ ) {
+			prop = handled[ index ];
+			tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 );
+			orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop );
+
+			if ( !( prop in dataShow ) ) {
+				dataShow[ prop ] = tween.start;
+				if ( hidden ) {
+					tween.end = tween.start;
+					tween.start = prop === "width" || prop === "height" ? 1 : 0;
+				}
+			}
+		}
+	}
+}
+
+function Tween( elem, options, prop, end, easing ) {
+	return new Tween.prototype.init( elem, options, prop, end, easing );
+}
+jQuery.Tween = Tween;
+
+Tween.prototype = {
+	constructor: Tween,
+	init: function( elem, options, prop, end, easing, unit ) {
+		this.elem = elem;
+		this.prop = prop;
+		this.easing = easing || "swing";
+		this.options = options;
+		this.start = this.now = this.cur();
+		this.end = end;
+		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
+	},
+	cur: function() {
+		var hooks = Tween.propHooks[ this.prop ];
+
+		return hooks && hooks.get ?
+			hooks.get( this ) :
+			Tween.propHooks._default.get( this );
+	},
+	run: function( percent ) {
+		var eased,
+			hooks = Tween.propHooks[ this.prop ];
+
+		if ( this.options.duration ) {
+			this.pos = eased = jQuery.easing[ this.easing ](
+				percent, this.options.duration * percent, 0, 1, this.options.duration
+			);
+		} else {
+			this.pos = eased = percent;
+		}
+		this.now = ( this.end - this.start ) * eased + this.start;
+
+		if ( this.options.step ) {
+			this.options.step.call( this.elem, this.now, this );
+		}
+
+		if ( hooks && hooks.set ) {
+			hooks.set( this );
+		} else {
+			Tween.propHooks._default.set( this );
+		}
+		return this;
+	}
+};
+
+Tween.prototype.init.prototype = Tween.prototype;
+
+Tween.propHooks = {
+	_default: {
+		get: function( tween ) {
+			var result;
+
+			if ( tween.elem[ tween.prop ] != null &&
+				(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
+				return tween.elem[ tween.prop ];
+			}
+
+			// passing an empty string as a 3rd parameter to .css will automatically
+			// attempt a parseFloat and fallback to a string if the parse fails
+			// so, simple values such as "10px" are parsed to Float.
+			// complex values such as "rotate(1rad)" are returned as is.
+			result = jQuery.css( tween.elem, tween.prop, "" );
+			// Empty strings, null, undefined and "auto" are converted to 0.
+			return !result || result === "auto" ? 0 : result;
+		},
+		set: function( tween ) {
+			// use step hook for back compat - use cssHook if its there - use .style if its
+			// available and use plain properties where available
+			if ( jQuery.fx.step[ tween.prop ] ) {
+				jQuery.fx.step[ tween.prop ]( tween );
+			} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
+				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
+			} else {
+				tween.elem[ tween.prop ] = tween.now;
+			}
+		}
+	}
+};
+
+// Remove in 2.0 - this supports IE8's panic based approach
+// to setting things on disconnected nodes
+
+Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
+	set: function( tween ) {
+		if ( tween.elem.nodeType && tween.elem.parentNode ) {
+			tween.elem[ tween.prop ] = tween.now;
+		}
+	}
+};
+
+jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
+	var cssFn = jQuery.fn[ name ];
+	jQuery.fn[ name ] = function( speed, easing, callback ) {
+		return speed == null || typeof speed === "boolean" ?
+			cssFn.apply( this, arguments ) :
+			this.animate( genFx( name, true ), speed, easing, callback );
+	};
+});
+
+jQuery.fn.extend({
+	fadeTo: function( speed, to, easing, callback ) {
+
+		// show any hidden elements after setting opacity to 0
+		return this.filter( isHidden ).css( "opacity", 0 ).show()
+
+			// animate to the value specified
+			.end().animate({ opacity: to }, speed, easing, callback );
+	},
+	animate: function( prop, speed, easing, callback ) {
+		var empty = jQuery.isEmptyObject( prop ),
+			optall = jQuery.speed( speed, easing, callback ),
+			doAnimation = function() {
+				// Operate on a copy of prop so per-property easing won't be lost
+				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
+				doAnimation.finish = function() {
+					anim.stop( true );
+				};
+				// Empty animations, or finishing resolves immediately
+				if ( empty || jQuery._data( this, "finish" ) ) {
+					anim.stop( true );
+				}
+			};
+			doAnimation.finish = doAnimation;
+
+		return empty || optall.queue === false ?
+			this.each( doAnimation ) :
+			this.queue( optall.queue, doAnimation );
+	},
+	stop: function( type, clearQueue, gotoEnd ) {
+		var stopQueue = function( hooks ) {
+			var stop = hooks.stop;
+			delete hooks.stop;
+			stop( gotoEnd );
+		};
+
+		if ( typeof type !== "string" ) {
+			gotoEnd = clearQueue;
+			clearQueue = type;
+			type = undefined;
+		}
+		if ( clearQueue && type !== false ) {
+			this.queue( type || "fx", [] );
+		}
+
+		return this.each(function() {
+			var dequeue = true,
+				index = type != null && type + "queueHooks",
+				timers = jQuery.timers,
+				data = jQuery._data( this );
+
+			if ( index ) {
+				if ( data[ index ] && data[ index ].stop ) {
+					stopQueue( data[ index ] );
+				}
+			} else {
+				for ( index in data ) {
+					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
+						stopQueue( data[ index ] );
+					}
+				}
+			}
+
+			for ( index = timers.length; index--; ) {
+				if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
+					timers[ index ].anim.stop( gotoEnd );
+					dequeue = false;
+					timers.splice( index, 1 );
+				}
+			}
+
+			// start the next in the queue if the last step wasn't forced
+			// timers currently will call their complete callbacks, which will dequeue
+			// but only if they were gotoEnd
+			if ( dequeue || !gotoEnd ) {
+				jQuery.dequeue( this, type );
+			}
+		});
+	},
+	finish: function( type ) {
+		if ( type !== false ) {
+			type = type || "fx";
+		}
+		return this.each(function() {
+			var index,
+				data = jQuery._data( this ),
+				queue = data[ type + "queue" ],
+				hooks = data[ type + "queueHooks" ],
+				timers = jQuery.timers,
+				length = queue ? queue.length : 0;
+
+			// enable finishing flag on private data
+			data.finish = true;
+
+			// empty the queue first
+			jQuery.queue( this, type, [] );
+
+			if ( hooks && hooks.cur && hooks.cur.finish ) {
+				hooks.cur.finish.call( this );
+			}
+
+			// look for any active animations, and finish them
+			for ( index = timers.length; index--; ) {
+				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
+					timers[ index ].anim.stop( true );
+					timers.splice( index, 1 );
+				}
+			}
+
+			// look for any animations in the old queue and finish them
+			for ( index = 0; index < length; index++ ) {
+				if ( queue[ index ] && queue[ index ].finish ) {
+					queue[ index ].finish.call( this );
+				}
+			}
+
+			// turn off finishing flag
+			delete data.finish;
+		});
+	}
+});
+
+// Generate parameters to create a standard animation
+function genFx( type, includeWidth ) {
+	var which,
+		attrs = { height: type },
+		i = 0;
+
+	// if we include width, step value is 1 to do all cssExpand values,
+	// if we don't include width, step value is 2 to skip over Left and Right
+	includeWidth = includeWidth? 1 : 0;
+	for( ; i < 4 ; i += 2 - includeWidth ) {
+		which = cssExpand[ i ];
+		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
+	}
+
+	if ( includeWidth ) {
+		attrs.opacity = attrs.width = type;
+	}
+
+	return attrs;
+}
+
+// Generate shortcuts for custom animations
+jQuery.each({
+	slideDown: genFx("show"),
+	slideUp: genFx("hide"),
+	slideToggle: genFx("toggle"),
+	fadeIn: { opacity: "show" },
+	fadeOut: { opacity: "hide" },
+	fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+	jQuery.fn[ name ] = function( speed, easing, callback ) {
+		return this.animate( props, speed, easing, callback );
+	};
+});
+
+jQuery.speed = function( speed, easing, fn ) {
+	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
+		complete: fn || !fn && easing ||
+			jQuery.isFunction( speed ) && speed,
+		duration: speed,
+		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
+	};
+
+	opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+		opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
+
+	// normalize opt.queue - true/undefined/null -> "fx"
+	if ( opt.queue == null || opt.queue === true ) {
+		opt.queue = "fx";
+	}
+
+	// Queueing
+	opt.old = opt.complete;
+
+	opt.complete = function() {
+		if ( jQuery.isFunction( opt.old ) ) {
+			opt.old.call( this );
+		}
+
+		if ( opt.queue ) {
+			jQuery.dequeue( this, opt.queue );
+		}
+	};
+
+	return opt;
+};
+
+jQuery.easing = {
+	linear: function( p ) {
+		return p;
+	},
+	swing: function( p ) {
+		return 0.5 - Math.cos( p*Math.PI ) / 2;
+	}
+};
+
+jQuery.timers = [];
+jQuery.fx = Tween.prototype.init;
+jQuery.fx.tick = function() {
+	var timer,
+		timers = jQuery.timers,
+		i = 0;
+
+	fxNow = jQuery.now();
+
+	for ( ; i < timers.length; i++ ) {
+		timer = timers[ i ];
+		// Checks the timer has not already been removed
+		if ( !timer() && timers[ i ] === timer ) {
+			timers.splice( i--, 1 );
+		}
+	}
+
+	if ( !timers.length ) {
+		jQuery.fx.stop();
+	}
+	fxNow = undefined;
+};
+
+jQuery.fx.timer = function( timer ) {
+	if ( timer() && jQuery.timers.push( timer ) ) {
+		jQuery.fx.start();
+	}
+};
+
+jQuery.fx.interval = 13;
+
+jQuery.fx.start = function() {
+	if ( !timerId ) {
+		timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
+	}
+};
+
+jQuery.fx.stop = function() {
+	clearInterval( timerId );
+	timerId = null;
+};
+
+jQuery.fx.speeds = {
+	slow: 600,
+	fast: 200,
+	// Default speed
+	_default: 400
+};
+
+// Back Compat <1.8 extension point
+jQuery.fx.step = {};
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+	jQuery.expr.filters.animated = function( elem ) {
+		return jQuery.grep(jQuery.timers, function( fn ) {
+			return elem === fn.elem;
+		}).length;
+	};
+}
+jQuery.fn.offset = function( options ) {
+	if ( arguments.length ) {
+		return options === undefined ?
+			this :
+			this.each(function( i ) {
+				jQuery.offset.setOffset( this, options, i );
+			});
+	}
+
+	var docElem, win,
+		box = { top: 0, left: 0 },
+		elem = this[ 0 ],
+		doc = elem && elem.ownerDocument;
+
+	if ( !doc ) {
+		return;
+	}
+
+	docElem = doc.documentElement;
+
+	// Make sure it's not a disconnected DOM node
+	if ( !jQuery.contains( docElem, elem ) ) {
+		return box;
+	}
+
+	// If we don't have gBCR, just use 0,0 rather than error
+	// BlackBerry 5, iOS 3 (original iPhone)
+	if ( typeof elem.getBoundingClientRect !== core_strundefined ) {
+		box = elem.getBoundingClientRect();
+	}
+	win = getWindow( doc );
+	return {
+		top: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),
+		left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
+	};
+};
+
+jQuery.offset = {
+
+	setOffset: function( elem, options, i ) {
+		var position = jQuery.css( elem, "position" );
+
+		// set position first, in-case top/left are set even on static elem
+		if ( position === "static" ) {
+			elem.style.position = "relative";
+		}
+
+		var curElem = jQuery( elem ),
+			curOffset = curElem.offset(),
+			curCSSTop = jQuery.css( elem, "top" ),
+			curCSSLeft = jQuery.css( elem, "left" ),
+			calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
+			props = {}, curPosition = {}, curTop, curLeft;
+
+		// need to be able to calculate position if either top or left is auto and position is either absolute or fixed
+		if ( calculatePosition ) {
+			curPosition = curElem.position();
+			curTop = curPosition.top;
+			curLeft = curPosition.left;
+		} else {
+			curTop = parseFloat( curCSSTop ) || 0;
+			curLeft = parseFloat( curCSSLeft ) || 0;
+		}
+
+		if ( jQuery.isFunction( options ) ) {
+			options = options.call( elem, i, curOffset );
+		}
+
+		if ( options.top != null ) {
+			props.top = ( options.top - curOffset.top ) + curTop;
+		}
+		if ( options.left != null ) {
+			props.left = ( options.left - curOffset.left ) + curLeft;
+		}
+
+		if ( "using" in options ) {
+			options.using.call( elem, props );
+		} else {
+			curElem.css( props );
+		}
+	}
+};
+
+
+jQuery.fn.extend({
+
+	position: function() {
+		if ( !this[ 0 ] ) {
+			return;
+		}
+
+		var offsetParent, offset,
+			parentOffset = { top: 0, left: 0 },
+			elem = this[ 0 ];
+
+		// fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
+		if ( jQuery.css( elem, "position" ) === "fixed" ) {
+			// we assume that getBoundingClientRect is available when computed position is fixed
+			offset = elem.getBoundingClientRect();
+		} else {
+			// Get *real* offsetParent
+			offsetParent = this.offsetParent();
+
+			// Get correct offsets
+			offset = this.offset();
+			if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
+				parentOffset = offsetParent.offset();
+			}
+
+			// Add offsetParent borders
+			parentOffset.top  += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
+			parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
+		}
+
+		// Subtract parent offsets and element margins
+		// note: when an element has margin: auto the offsetLeft and marginLeft
+		// are the same in Safari causing offset.left to incorrectly be 0
+		return {
+			top:  offset.top  - parentOffset.top - jQuery.css( elem, "marginTop", true ),
+			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
+		};
+	},
+
+	offsetParent: function() {
+		return this.map(function() {
+			var offsetParent = this.offsetParent || document.documentElement;
+			while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) {
+				offsetParent = offsetParent.offsetParent;
+			}
+			return offsetParent || document.documentElement;
+		});
+	}
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
+	var top = /Y/.test( prop );
+
+	jQuery.fn[ method ] = function( val ) {
+		return jQuery.access( this, function( elem, method, val ) {
+			var win = getWindow( elem );
+
+			if ( val === undefined ) {
+				return win ? (prop in win) ? win[ prop ] :
+					win.document.documentElement[ method ] :
+					elem[ method ];
+			}
+
+			if ( win ) {
+				win.scrollTo(
+					!top ? val : jQuery( win ).scrollLeft(),
+					top ? val : jQuery( win ).scrollTop()
+				);
+
+			} else {
+				elem[ method ] = val;
+			}
+		}, method, val, arguments.length, null );
+	};
+});
+
+function getWindow( elem ) {
+	return jQuery.isWindow( elem ) ?
+		elem :
+		elem.nodeType === 9 ?
+			elem.defaultView || elem.parentWindow :
+			false;
+}
+// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
+jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
+	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
+		// margin is only for outerHeight, outerWidth
+		jQuery.fn[ funcName ] = function( margin, value ) {
+			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
+				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
+
+			return jQuery.access( this, function( elem, type, value ) {
+				var doc;
+
+				if ( jQuery.isWindow( elem ) ) {
+					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
+					// isn't a whole lot we can do. See pull request at this URL for discussion:
+					// https://github.com/jquery/jquery/pull/764
+					return elem.document.documentElement[ "client" + name ];
+				}
+
+				// Get document width or height
+				if ( elem.nodeType === 9 ) {
+					doc = elem.documentElement;
+
+					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
+					// unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
+					return Math.max(
+						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
+						elem.body[ "offset" + name ], doc[ "offset" + name ],
+						doc[ "client" + name ]
+					);
+				}
+
+				return value === undefined ?
+					// Get width or height on the element, requesting but not forcing parseFloat
+					jQuery.css( elem, type, extra ) :
+
+					// Set width or height on the element
+					jQuery.style( elem, type, value, extra );
+			}, type, chainable ? margin : undefined, chainable, null );
+		};
+	});
+});
+// Limit scope pollution from any deprecated API
+// (function() {
+
+// })();
+// Expose jQuery to the global object
+window.jQuery = window.$ = jQuery;
+
+// Expose jQuery as an AMD module, but only for AMD loaders that
+// understand the issues with loading multiple versions of jQuery
+// in a page that all might call define(). The loader will indicate
+// they have special allowances for multiple jQuery versions by
+// specifying define.amd.jQuery = true. Register as a named module,
+// since jQuery can be concatenated with other files that may use define,
+// but not use a proper concatenation script that understands anonymous
+// AMD modules. A named AMD is safest and most robust way to register.
+// Lowercase jquery is used because AMD module names are derived from
+// file names, and jQuery is normally delivered in a lowercase file name.
+// Do this after creating the global so that if an AMD module wants to call
+// noConflict to hide this version of jQuery, it will work.
+if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
+	define( "jquery", [], function () { return jQuery; } );
+}
+
+})( window );
diff --git a/sdncon/ui/static/js/thirdparty/jquery-1.9.1.min.js b/sdncon/ui/static/js/thirdparty/jquery-1.9.1.min.js
new file mode 100755
index 0000000..006e953
--- /dev/null
+++ b/sdncon/ui/static/js/thirdparty/jquery-1.9.1.min.js
@@ -0,0 +1,5 @@
+/*! jQuery v1.9.1 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license
+//@ sourceMappingURL=jquery.min.map
+*/(function(e,t){var n,r,i=typeof t,o=e.document,a=e.location,s=e.jQuery,u=e.$,l={},c=[],p="1.9.1",f=c.concat,d=c.push,h=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,b=function(e,t){return new b.fn.init(e,t,r)},x=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^[\],:{}\s]*$/,E=/(?:^|:|,)(?:\s*\[)+/g,S=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,A=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,j=/^-ms-/,D=/-([\da-z])/gi,L=function(e,t){return t.toUpperCase()},H=function(e){(o.addEventListener||"load"===e.type||"complete"===o.readyState)&&(q(),b.ready())},q=function(){o.addEventListener?(o.removeEventListener("DOMContentLoaded",H,!1),e.removeEventListener("load",H,!1)):(o.detachEvent("onreadystatechange",H),e.detachEvent("onload",H))};b.fn=b.prototype={jquery:p,constructor:b,init:function(e,n,r){var i,a;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof b?n[0]:n,b.merge(this,b.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:o,!0)),C.test(i[1])&&b.isPlainObject(n))for(i in n)b.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(a=o.getElementById(i[2]),a&&a.parentNode){if(a.id!==i[2])return r.find(e);this.length=1,this[0]=a}return this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):b.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),b.makeArray(e,this))},selector:"",length:0,size:function(){return this.length},toArray:function(){return h.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=b.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return b.each(this,e,t)},ready:function(e){return b.ready.promise().done(e),this},slice:function(){return this.pushStack(h.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(b.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:d,sort:[].sort,splice:[].splice},b.fn.init.prototype=b.fn,b.extend=b.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},u=1,l=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},u=2),"object"==typeof s||b.isFunction(s)||(s={}),l===u&&(s=this,--u);l>u;u++)if(null!=(o=arguments[u]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(b.isPlainObject(r)||(n=b.isArray(r)))?(n?(n=!1,a=e&&b.isArray(e)?e:[]):a=e&&b.isPlainObject(e)?e:{},s[i]=b.extend(c,a,r)):r!==t&&(s[i]=r));return s},b.extend({noConflict:function(t){return e.$===b&&(e.$=u),t&&e.jQuery===b&&(e.jQuery=s),b},isReady:!1,readyWait:1,holdReady:function(e){e?b.readyWait++:b.ready(!0)},ready:function(e){if(e===!0?!--b.readyWait:!b.isReady){if(!o.body)return setTimeout(b.ready);b.isReady=!0,e!==!0&&--b.readyWait>0||(n.resolveWith(o,[b]),b.fn.trigger&&b(o).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===b.type(e)},isArray:Array.isArray||function(e){return"array"===b.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if(!e||"object"!==b.type(e)||e.nodeType||b.isWindow(e))return!1;try{if(e.constructor&&!y.call(e,"constructor")&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||y.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=b.buildFragment([e],t,i),i&&b(i).remove(),b.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=b.trim(n),n&&k.test(n.replace(S,"@").replace(A,"]").replace(E,"")))?Function("return "+n)():(b.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||b.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&b.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(j,"ms-").replace(D,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:v&&!v.call("\ufeff\u00a0")?function(e){return null==e?"":v.call(e)}:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?b.merge(n,"string"==typeof e?[e]:e):d.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(g)return g.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return f.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),b.isFunction(e)?(r=h.call(arguments,2),i=function(){return e.apply(n||this,r.concat(h.call(arguments)))},i.guid=e.guid=e.guid||b.guid++,i):t},access:function(e,n,r,i,o,a,s){var u=0,l=e.length,c=null==r;if("object"===b.type(r)){o=!0;for(u in r)b.access(e,n,u,r[u],!0,a,s)}else if(i!==t&&(o=!0,b.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(b(e),n)})),n))for(;l>u;u++)n(e[u],r,s?i:i.call(e[u],u,n(e[u],r)));return o?e:c?n.call(e):l?n(e[0],r):a},now:function(){return(new Date).getTime()}}),b.ready.promise=function(t){if(!n)if(n=b.Deferred(),"complete"===o.readyState)setTimeout(b.ready);else if(o.addEventListener)o.addEventListener("DOMContentLoaded",H,!1),e.addEventListener("load",H,!1);else{o.attachEvent("onreadystatechange",H),e.attachEvent("onload",H);var r=!1;try{r=null==e.frameElement&&o.documentElement}catch(i){}r&&r.doScroll&&function a(){if(!b.isReady){try{r.doScroll("left")}catch(e){return setTimeout(a,50)}q(),b.ready()}}()}return n.promise(t)},b.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=b.type(e);return b.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=b(o);var _={};function F(e){var t=_[e]={};return b.each(e.match(w)||[],function(e,n){t[n]=!0}),t}b.Callbacks=function(e){e="string"==typeof e?_[e]||F(e):b.extend({},e);var n,r,i,o,a,s,u=[],l=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=u.length,n=!0;u&&o>a;a++)if(u[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,u&&(l?l.length&&c(l.shift()):r?u=[]:p.disable())},p={add:function(){if(u){var t=u.length;(function i(t){b.each(t,function(t,n){var r=b.type(n);"function"===r?e.unique&&p.has(n)||u.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=u.length:r&&(s=t,c(r))}return this},remove:function(){return u&&b.each(arguments,function(e,t){var r;while((r=b.inArray(t,u,r))>-1)u.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?b.inArray(e,u)>-1:!(!u||!u.length)},empty:function(){return u=[],this},disable:function(){return u=l=r=t,this},disabled:function(){return!u},lock:function(){return l=t,r||p.disable(),this},locked:function(){return!l},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],!u||i&&!l||(n?l.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},b.extend({Deferred:function(e){var t=[["resolve","done",b.Callbacks("once memory"),"resolved"],["reject","fail",b.Callbacks("once memory"),"rejected"],["notify","progress",b.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return b.Deferred(function(n){b.each(t,function(t,o){var a=o[0],s=b.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&b.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?b.extend(e,r):r}},i={};return r.pipe=r.then,b.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=h.call(arguments),r=n.length,i=1!==r||e&&b.isFunction(e.promise)?r:0,o=1===i?e:b.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?h.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,u,l;if(r>1)for(s=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&b.isFunction(n[t].promise)?n[t].promise().done(a(t,l,n)).fail(o.reject).progress(a(t,u,s)):--i;return i||o.resolveWith(l,n),o.promise()}}),b.support=function(){var t,n,r,a,s,u,l,c,p,f,d=o.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=d.getElementsByTagName("*"),r=d.getElementsByTagName("a")[0],!n||!r||!n.length)return{};s=o.createElement("select"),l=s.appendChild(o.createElement("option")),a=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={getSetAttribute:"t"!==d.className,leadingWhitespace:3===d.firstChild.nodeType,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:"/a"===r.getAttribute("href"),opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:!!a.value,optSelected:l.selected,enctype:!!o.createElement("form").enctype,html5Clone:"<:nav></:nav>"!==o.createElement("nav").cloneNode(!0).outerHTML,boxModel:"CSS1Compat"===o.compatMode,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},a.checked=!0,t.noCloneChecked=a.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!l.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}a=o.createElement("input"),a.setAttribute("value",""),t.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),t.radioValue="t"===a.value,a.setAttribute("checked","t"),a.setAttribute("name","t"),u=o.createDocumentFragment(),u.appendChild(a),t.appendChecked=a.checked,t.checkClone=u.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;return d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip,b(function(){var n,r,a,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",u=o.getElementsByTagName("body")[0];u&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",u.appendChild(n).appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",a=d.getElementsByTagName("td"),a[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===a[0].offsetHeight,a[0].style.display="",a[1].style.display="none",t.reliableHiddenOffsets=p&&0===a[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=4===d.offsetWidth,t.doesNotIncludeMarginInBodyOffset=1!==u.offsetTop,e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(o.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="<div></div>",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(u.style.zoom=1)),u.removeChild(n),n=d=a=r=null)}),n=s=u=l=r=a=null,t}();var O=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,B=/([A-Z])/g;function P(e,n,r,i){if(b.acceptData(e)){var o,a,s=b.expando,u="string"==typeof n,l=e.nodeType,p=l?b.cache:e,f=l?e[s]:e[s]&&s;if(f&&p[f]&&(i||p[f].data)||!u||r!==t)return f||(l?e[s]=f=c.pop()||b.guid++:f=s),p[f]||(p[f]={},l||(p[f].toJSON=b.noop)),("object"==typeof n||"function"==typeof n)&&(i?p[f]=b.extend(p[f],n):p[f].data=b.extend(p[f].data,n)),o=p[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[b.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[b.camelCase(n)])):a=o,a}}function R(e,t,n){if(b.acceptData(e)){var r,i,o,a=e.nodeType,s=a?b.cache:e,u=a?e[b.expando]:b.expando;if(s[u]){if(t&&(o=n?s[u]:s[u].data)){b.isArray(t)?t=t.concat(b.map(t,b.camelCase)):t in o?t=[t]:(t=b.camelCase(t),t=t in o?[t]:t.split(" "));for(r=0,i=t.length;i>r;r++)delete o[t[r]];if(!(n?$:b.isEmptyObject)(o))return}(n||(delete s[u].data,$(s[u])))&&(a?b.cleanData([e],!0):b.support.deleteExpando||s!=s.window?delete s[u]:s[u]=null)}}}b.extend({cache:{},expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?b.cache[e[b.expando]]:e[b.expando],!!e&&!$(e)},data:function(e,t,n){return P(e,t,n)},removeData:function(e,t){return R(e,t)},_data:function(e,t,n){return P(e,t,n,!0)},_removeData:function(e,t){return R(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&b.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),b.fn.extend({data:function(e,n){var r,i,o=this[0],a=0,s=null;if(e===t){if(this.length&&(s=b.data(o),1===o.nodeType&&!b._data(o,"parsedAttrs"))){for(r=o.attributes;r.length>a;a++)i=r[a].name,i.indexOf("data-")||(i=b.camelCase(i.slice(5)),W(o,i,s[i]));b._data(o,"parsedAttrs",!0)}return s}return"object"==typeof e?this.each(function(){b.data(this,e)}):b.access(this,function(n){return n===t?o?W(o,e,b.data(o,e)):null:(this.each(function(){b.data(this,e,n)}),t)},null,n,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){b.removeData(this,e)})}});function W(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(B,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:O.test(r)?b.parseJSON(r):r}catch(o){}b.data(e,n,r)}else r=t}return r}function $(e){var t;for(t in e)if(("data"!==t||!b.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}b.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=b._data(e,n),r&&(!i||b.isArray(r)?i=b._data(e,n,b.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=b.queue(e,t),r=n.length,i=n.shift(),o=b._queueHooks(e,t),a=function(){b.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),o.cur=i,i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return b._data(e,n)||b._data(e,n,{empty:b.Callbacks("once memory").add(function(){b._removeData(e,t+"queue"),b._removeData(e,n)})})}}),b.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?b.queue(this[0],e):n===t?this:this.each(function(){var t=b.queue(this,e,n);b._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&b.dequeue(this,e)})},dequeue:function(e){return this.each(function(){b.dequeue(this,e)})},delay:function(e,t){return e=b.fx?b.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=b.Deferred(),a=this,s=this.length,u=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=b._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(u));return u(),o.promise(n)}});var I,z,X=/[\t\r\n]/g,U=/\r/g,V=/^(?:input|select|textarea|button|object)$/i,Y=/^(?:a|area)$/i,J=/^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,G=/^(?:checked|selected)$/i,Q=b.support.getSetAttribute,K=b.support.input;b.fn.extend({attr:function(e,t){return b.access(this,b.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){b.removeAttr(this,e)})},prop:function(e,t){return b.access(this,b.prop,e,t,arguments.length>1)},removeProp:function(e){return e=b.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,u="string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=b.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,u=0===arguments.length||"string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?b.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,r="boolean"==typeof t;return b.isFunction(e)?this.each(function(n){b(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var o,a=0,s=b(this),u=t,l=e.match(w)||[];while(o=l[a++])u=r?u:!s.hasClass(o),s[u?"addClass":"removeClass"](o)}else(n===i||"boolean"===n)&&(this.className&&b._data(this,"__className__",this.className),this.className=this.className||e===!1?"":b._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(X," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=b.isFunction(e),this.each(function(n){var o,a=b(this);1===this.nodeType&&(o=i?e.call(this,n,a.val()):e,null==o?o="":"number"==typeof o?o+="":b.isArray(o)&&(o=b.map(o,function(e){return null==e?"":e+""})),r=b.valHooks[this.type]||b.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=b.valHooks[o.type]||b.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(U,""):null==n?"":n)}}}),b.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,u=0>i?s:o?i:0;for(;s>u;u++)if(n=r[u],!(!n.selected&&u!==i||(b.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&b.nodeName(n.parentNode,"optgroup"))){if(t=b(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n=b.makeArray(t);return b(e).find("option").each(function(){this.selected=b.inArray(b(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attr:function(e,n,r){var o,a,s,u=e.nodeType;if(e&&3!==u&&8!==u&&2!==u)return typeof e.getAttribute===i?b.prop(e,n,r):(a=1!==u||!b.isXMLDoc(e),a&&(n=n.toLowerCase(),o=b.attrHooks[n]||(J.test(n)?z:I)),r===t?o&&a&&"get"in o&&null!==(s=o.get(e,n))?s:(typeof e.getAttribute!==i&&(s=e.getAttribute(n)),null==s?t:s):null!==r?o&&a&&"set"in o&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r):(b.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=b.propFix[n]||n,J.test(n)?!Q&&G.test(n)?e[b.camelCase("default-"+n)]=e[r]=!1:e[r]=!1:b.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!b.support.radioValue&&"radio"===t&&b.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!b.isXMLDoc(e),a&&(n=b.propFix[n]||n,o=b.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):V.test(e.nodeName)||Y.test(e.nodeName)&&e.href?0:t}}}}),z={get:function(e,n){var r=b.prop(e,n),i="boolean"==typeof r&&e.getAttribute(n),o="boolean"==typeof r?K&&Q?null!=i:G.test(n)?e[b.camelCase("default-"+n)]:!!i:e.getAttributeNode(n);return o&&o.value!==!1?n.toLowerCase():t},set:function(e,t,n){return t===!1?b.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&b.propFix[n]||n,n):e[b.camelCase("default-"+n)]=e[n]=!0,n}},K&&Q||(b.attrHooks.value={get:function(e,n){var r=e.getAttributeNode(n);return b.nodeName(e,"input")?e.defaultValue:r&&r.specified?r.value:t},set:function(e,n,r){return b.nodeName(e,"input")?(e.defaultValue=n,t):I&&I.set(e,n,r)}}),Q||(I=b.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&("id"===n||"name"===n||"coords"===n?""!==r.value:r.specified)?r.value:t},set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},b.attrHooks.contenteditable={get:I.get,set:function(e,t,n){I.set(e,""===t?!1:t,n)}},b.each(["width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}})})),b.support.hrefNormalized||(b.each(["href","src","width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return null==r?t:r}})}),b.each(["href","src"],function(e,t){b.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}})),b.support.style||(b.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),b.support.optSelected||(b.propHooks.selected=b.extend(b.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),b.support.enctype||(b.propFix.enctype="encoding"),b.support.checkOn||b.each(["radio","checkbox"],function(){b.valHooks[this]={get:function(e){return null===e.getAttribute("value")?"on":e.value}}}),b.each(["radio","checkbox"],function(){b.valHooks[this]=b.extend(b.valHooks[this],{set:function(e,n){return b.isArray(n)?e.checked=b.inArray(b(e).val(),n)>=0:t}})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}b.event={global:{},add:function(e,n,r,o,a){var s,u,l,c,p,f,d,h,g,m,y,v=b._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=b.guid++),(u=v.events)||(u=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof b===i||e&&b.event.triggered===e.type?t:b.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(w)||[""],l=n.length;while(l--)s=rt.exec(n[l])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),p=b.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=b.event.special[g]||{},d=b.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&b.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=u[g])||(h=u[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),b.event.global[g]=!0;e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,p,f,d,h,g,m=b.hasData(e)&&b._data(e);if(m&&(c=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(s=rt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=b.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),u=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));u&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||b.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)b.event.remove(e,d+t[l],n,r,!0);b.isEmptyObject(c)&&(delete m.handle,b._removeData(e,"events"))}},trigger:function(n,r,i,a){var s,u,l,c,p,f,d,h=[i||o],g=y.call(n,"type")?n.type:n,m=y.call(n,"namespace")?n.namespace.split("."):[];if(l=f=i=i||o,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+b.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),u=0>g.indexOf(":")&&"on"+g,n=n[b.expando]?n:new b.Event(g,"object"==typeof n&&n),n.isTrigger=!0,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:b.makeArray(r,[n]),p=b.event.special[g]||{},a||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!a&&!p.noBubble&&!b.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(l=l.parentNode);l;l=l.parentNode)h.push(l),f=l;f===(i.ownerDocument||o)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((l=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(b._data(l,"events")||{})[n.type]&&b._data(l,"handle"),s&&s.apply(l,r),s=u&&l[u],s&&b.acceptData(l)&&s.apply&&s.apply(l,r)===!1&&n.preventDefault();if(n.type=g,!(a||n.isDefaultPrevented()||p._default&&p._default.apply(i.ownerDocument,r)!==!1||"click"===g&&b.nodeName(i,"a")||!b.acceptData(i)||!u||!i[g]||b.isWindow(i))){f=i[u],f&&(i[u]=null),b.event.triggered=g;try{i[g]()}catch(v){}b.event.triggered=t,f&&(i[u]=f)}return n.result}},dispatch:function(e){e=b.event.fix(e);var n,r,i,o,a,s=[],u=h.call(arguments),l=(b._data(this,"events")||{})[e.type]||[],c=b.event.special[e.type]||{};if(u[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=b.event.handlers.call(this,e,l),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((b.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,u),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],u=n.delegateCount,l=e.target;if(u&&l.nodeType&&(!e.button||"click"!==e.type))for(;l!=this;l=l.parentNode||this)if(1===l.nodeType&&(l.disabled!==!0||"click"!==e.type)){for(o=[],a=0;u>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?b(r,this).index(l)>=0:b.find(r,this,null,[l]).length),o[r]&&o.push(i);o.length&&s.push({elem:l,handlers:o})}return n.length>u&&s.push({elem:this,handlers:n.slice(u)}),s},fix:function(e){if(e[b.expando])return e;var t,n,r,i=e.type,a=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new b.Event(a),t=r.length;while(t--)n=r[t],e[n]=a[n];return e.target||(e.target=a.srcElement||o),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,a):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,a,s=n.button,u=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||o,a=i.documentElement,r=i.body,e.pageX=n.clientX+(a&&a.scrollLeft||r&&r.scrollLeft||0)-(a&&a.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(a&&a.scrollTop||r&&r.scrollTop||0)-(a&&a.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&u&&(e.relatedTarget=u===e.target?n.toElement:u),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},click:{trigger:function(){return b.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t}},focus:{trigger:function(){if(this!==o.activeElement&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===o.activeElement&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=b.extend(new b.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?b.event.trigger(i,null,t):b.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},b.removeEvent=o.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},b.Event=function(e,n){return this instanceof b.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&b.extend(this,n),this.timeStamp=e&&e.timeStamp||b.now(),this[b.expando]=!0,t):new b.Event(e,n)},b.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},b.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){b.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;
+return(!i||i!==r&&!b.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),b.support.submitBubbles||(b.event.special.submit={setup:function(){return b.nodeName(this,"form")?!1:(b.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=b.nodeName(n,"input")||b.nodeName(n,"button")?n.form:t;r&&!b._data(r,"submitBubbles")&&(b.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),b._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&b.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return b.nodeName(this,"form")?!1:(b.event.remove(this,"._submit"),t)}}),b.support.changeBubbles||(b.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(b.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),b.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),b.event.simulate("change",this,e,!0)})),!1):(b.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!b._data(t,"changeBubbles")&&(b.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||b.event.simulate("change",this.parentNode,e,!0)}),b._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return b.event.remove(this,"._change"),!Z.test(this.nodeName)}}),b.support.focusinBubbles||b.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){b.event.simulate(t,e.target,b.event.fix(e),!0)};b.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),b.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return b().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=b.guid++)),this.each(function(){b.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,b(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){b.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){b.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?b.event.trigger(e,n,r,!0):t}}),function(e,t){var n,r,i,o,a,s,u,l,c,p,f,d,h,g,m,y,v,x="sizzle"+-new Date,w=e.document,T={},N=0,C=0,k=it(),E=it(),S=it(),A=typeof t,j=1<<31,D=[],L=D.pop,H=D.push,q=D.slice,M=D.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},_="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=F.replace("w","w#"),B="([*^$|!~]?=)",P="\\["+_+"*("+F+")"+_+"*(?:"+B+_+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+O+")|)|)"+_+"*\\]",R=":("+F+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+P.replace(3,8)+")*)|.*)\\)|)",W=RegExp("^"+_+"+|((?:^|[^\\\\])(?:\\\\.)*)"+_+"+$","g"),$=RegExp("^"+_+"*,"+_+"*"),I=RegExp("^"+_+"*([\\x20\\t\\r\\n\\f>+~])"+_+"*"),z=RegExp(R),X=RegExp("^"+O+"$"),U={ID:RegExp("^#("+F+")"),CLASS:RegExp("^\\.("+F+")"),NAME:RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:RegExp("^("+F.replace("w","w*")+")"),ATTR:RegExp("^"+P),PSEUDO:RegExp("^"+R),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+_+"*(even|odd|(([+-]|)(\\d*)n|)"+_+"*(?:([+-]|)"+_+"*(\\d+)|))"+_+"*\\)|)","i"),needsContext:RegExp("^"+_+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+_+"*((?:-\\d)?\\d*)"+_+"*\\)|)(?=[^-]|$)","i")},V=/[\x20\t\r\n\f]*[+~]/,Y=/^[^{]+\{\s*\[native code/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,G=/^(?:input|select|textarea|button)$/i,Q=/^h\d$/i,K=/'|\\/g,Z=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,et=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,tt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{q.call(w.documentElement.childNodes,0)[0].nodeType}catch(nt){q=function(e){var t,n=[];while(t=this[e++])n.push(t);return n}}function rt(e){return Y.test(e+"")}function it(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>i.cacheLength&&delete e[t.shift()],e[n]=r}}function ot(e){return e[x]=!0,e}function at(e){var t=p.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}}function st(e,t,n,r){var i,o,a,s,u,l,f,g,m,v;if((t?t.ownerDocument||t:w)!==p&&c(t),t=t||p,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(!d&&!r){if(i=J.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&y(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return H.apply(n,q.call(t.getElementsByTagName(e),0)),n;if((a=i[3])&&T.getByClassName&&t.getElementsByClassName)return H.apply(n,q.call(t.getElementsByClassName(a),0)),n}if(T.qsa&&!h.test(e)){if(f=!0,g=x,m=t,v=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){l=ft(e),(f=t.getAttribute("id"))?g=f.replace(K,"\\$&"):t.setAttribute("id",g),g="[id='"+g+"'] ",u=l.length;while(u--)l[u]=g+dt(l[u]);m=V.test(e)&&t.parentNode||t,v=l.join(",")}if(v)try{return H.apply(n,q.call(m.querySelectorAll(v),0)),n}catch(b){}finally{f||t.removeAttribute("id")}}}return wt(e.replace(W,"$1"),t,n,r)}a=st.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},c=st.setDocument=function(e){var n=e?e.ownerDocument||e:w;return n!==p&&9===n.nodeType&&n.documentElement?(p=n,f=n.documentElement,d=a(n),T.tagNameNoComments=at(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),T.attributes=at(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),T.getByClassName=at(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),T.getByName=at(function(e){e.id=x+0,e.innerHTML="<a name='"+x+"'></a><div name='"+x+"'></div>",f.insertBefore(e,f.firstChild);var t=n.getElementsByName&&n.getElementsByName(x).length===2+n.getElementsByName(x+0).length;return T.getIdNotName=!n.getElementById(x),f.removeChild(e),t}),i.attrHandle=at(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==A&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},T.getIdNotName?(i.find.ID=function(e,t){if(typeof t.getElementById!==A&&!d){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){return e.getAttribute("id")===t}}):(i.find.ID=function(e,n){if(typeof n.getElementById!==A&&!d){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==A&&r.getAttributeNode("id").value===e?[r]:t:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){var n=typeof e.getAttributeNode!==A&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=T.tagNameNoComments?function(e,n){return typeof n.getElementsByTagName!==A?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.NAME=T.getByName&&function(e,n){return typeof n.getElementsByName!==A?n.getElementsByName(name):t},i.find.CLASS=T.getByClassName&&function(e,n){return typeof n.getElementsByClassName===A||d?t:n.getElementsByClassName(e)},g=[],h=[":focus"],(T.qsa=rt(n.querySelectorAll))&&(at(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||h.push("\\["+_+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||h.push(":checked")}),at(function(e){e.innerHTML="<input type='hidden' i=''/>",e.querySelectorAll("[i^='']").length&&h.push("[*^$]="+_+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||h.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),h.push(",.*:")})),(T.matchesSelector=rt(m=f.matchesSelector||f.mozMatchesSelector||f.webkitMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&at(function(e){T.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",R)}),h=RegExp(h.join("|")),g=RegExp(g.join("|")),y=rt(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},v=f.compareDocumentPosition?function(e,t){var r;return e===t?(u=!0,0):(r=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t))?1&r||e.parentNode&&11===e.parentNode.nodeType?e===n||y(w,e)?-1:t===n||y(w,t)?1:0:4&r?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return u=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:0;if(o===a)return ut(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?ut(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},u=!1,[0,0].sort(v),T.detectDuplicates=u,p):p},st.matches=function(e,t){return st(e,null,null,t)},st.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Z,"='$1']"),!(!T.matchesSelector||d||g&&g.test(t)||h.test(t)))try{var n=m.call(e,t);if(n||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return st(t,p,null,[e]).length>0},st.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},st.attr=function(e,t){var n;return(e.ownerDocument||e)!==p&&c(e),d||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):d||T.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},st.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},st.uniqueSort=function(e){var t,n=[],r=1,i=0;if(u=!T.detectDuplicates,e.sort(v),u){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e};function ut(e,t){var n=t&&e,r=n&&(~t.sourceIndex||j)-(~e.sourceIndex||j);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function lt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ct(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function pt(e){return ot(function(t){return t=+t,ot(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}o=st.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=st.selectors={cacheLength:50,createPseudo:ot,match:U,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(et,tt),e[3]=(e[4]||e[5]||"").replace(et,tt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||st.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&st.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return U.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&z.test(n)&&(t=ft(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(et,tt).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[e+" "];return t||(t=RegExp("(^|"+_+")"+e+"("+_+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==A&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=st.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[x]||(m[x]={}),l=c[e]||[],d=l[0]===N&&l[1],f=l[0]===N&&l[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[N,d,f];break}}else if(v&&(l=(t[x]||(t[x]={}))[e])&&l[0]===N)f=l[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[x]||(p[x]={}))[e]=[N,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||st.error("unsupported pseudo: "+e);return r[x]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?ot(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=M.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:ot(function(e){var t=[],n=[],r=s(e.replace(W,"$1"));return r[x]?ot(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:ot(function(e){return function(t){return st(e,t).length>0}}),contains:ot(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:ot(function(e){return X.test(e||"")||st.error("unsupported lang: "+e),e=e.replace(et,tt).toLowerCase(),function(t){var n;do if(n=d?t.getAttribute("xml:lang")||t.getAttribute("lang"):t.lang)return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return Q.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:pt(function(){return[0]}),last:pt(function(e,t){return[t-1]}),eq:pt(function(e,t,n){return[0>n?n+t:n]}),even:pt(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:pt(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:pt(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:pt(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}};for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[n]=lt(n);for(n in{submit:!0,reset:!0})i.pseudos[n]=ct(n);function ft(e,t){var n,r,o,a,s,u,l,c=E[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=i.preFilter;while(s){(!n||(r=$.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),u.push(o=[])),n=!1,(r=I.exec(s))&&(n=r.shift(),o.push({value:n,type:r[0].replace(W," ")}),s=s.slice(n.length));for(a in i.filter)!(r=U[a].exec(s))||l[a]&&!(r=l[a](r))||(n=r.shift(),o.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?st.error(e):E(e,u).slice(0)}function dt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function ht(e,t,n){var i=t.dir,o=n&&"parentNode"===i,a=C++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,s){var u,l,c,p=N+" "+a;if(s){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[x]||(t[x]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,s)||r,l[1]===!0)return!0}}function gt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function mt(e,t,n,r,i){var o,a=[],s=0,u=e.length,l=null!=t;for(;u>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),l&&t.push(s));return a}function yt(e,t,n,r,i,o){return r&&!r[x]&&(r=yt(r)),i&&!i[x]&&(i=yt(i,o)),ot(function(o,a,s,u){var l,c,p,f=[],d=[],h=a.length,g=o||xt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:mt(g,f,e,s,u),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,u),r){l=mt(y,d),r(l,[],s,u),c=l.length;while(c--)(p=l[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?M.call(o,p):f[c])>-1&&(o[l]=!(a[l]=p))}}else y=mt(y===a?y.splice(h,y.length):y),i?i(null,a,y,u):H.apply(a,y)})}function vt(e){var t,n,r,o=e.length,a=i.relative[e[0].type],s=a||i.relative[" "],u=a?1:0,c=ht(function(e){return e===t},s,!0),p=ht(function(e){return M.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>u;u++)if(n=i.relative[e[u].type])f=[ht(gt(f),n)];else{if(n=i.filter[e[u].type].apply(null,e[u].matches),n[x]){for(r=++u;o>r;r++)if(i.relative[e[r].type])break;return yt(u>1&&gt(f),u>1&&dt(e.slice(0,u-1)).replace(W,"$1"),n,r>u&&vt(e.slice(u,r)),o>r&&vt(e=e.slice(r)),o>r&&dt(e))}f.push(n)}return gt(f)}function bt(e,t){var n=0,o=t.length>0,a=e.length>0,s=function(s,u,c,f,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,T=l,C=s||a&&i.find.TAG("*",d&&u.parentNode||u),k=N+=null==T?1:Math.random()||.1;for(w&&(l=u!==p&&u,r=n);null!=(h=C[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,u,c)){f.push(h);break}w&&(N=k,r=++n)}o&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,o&&b!==v){g=0;while(m=t[g++])m(x,y,u,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=L.call(f));y=mt(y)}H.apply(f,y),w&&!s&&y.length>0&&v+t.length>1&&st.uniqueSort(f)}return w&&(N=k,l=T),x};return o?ot(s):s}s=st.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=ft(e)),n=t.length;while(n--)o=vt(t[n]),o[x]?r.push(o):i.push(o);o=S(e,bt(i,r))}return o};function xt(e,t,n){var r=0,i=t.length;for(;i>r;r++)st(e,t[r],n);return n}function wt(e,t,n,r){var o,a,u,l,c,p=ft(e);if(!r&&1===p.length){if(a=p[0]=p[0].slice(0),a.length>2&&"ID"===(u=a[0]).type&&9===t.nodeType&&!d&&i.relative[a[1].type]){if(t=i.find.ID(u.matches[0].replace(et,tt),t)[0],!t)return n;e=e.slice(a.shift().value.length)}o=U.needsContext.test(e)?0:a.length;while(o--){if(u=a[o],i.relative[l=u.type])break;if((c=i.find[l])&&(r=c(u.matches[0].replace(et,tt),V.test(a[0].type)&&t.parentNode||t))){if(a.splice(o,1),e=r.length&&dt(a),!e)return H.apply(n,q.call(r,0)),n;break}}}return s(e,p)(r,t,d,n,V.test(e)),n}i.pseudos.nth=i.pseudos.eq;function Tt(){}i.filters=Tt.prototype=i.pseudos,i.setFilters=new Tt,c(),st.attr=b.attr,b.find=st,b.expr=st.selectors,b.expr[":"]=b.expr.pseudos,b.unique=st.uniqueSort,b.text=st.getText,b.isXMLDoc=st.isXML,b.contains=st.contains}(e);var at=/Until$/,st=/^(?:parents|prev(?:Until|All))/,ut=/^.[^:#\[\.,]*$/,lt=b.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};b.fn.extend({find:function(e){var t,n,r,i=this.length;if("string"!=typeof e)return r=this,this.pushStack(b(e).filter(function(){for(t=0;i>t;t++)if(b.contains(r[t],this))return!0}));for(n=[],t=0;i>t;t++)b.find(e,this[t],n);return n=this.pushStack(i>1?b.unique(n):n),n.selector=(this.selector?this.selector+" ":"")+e,n},has:function(e){var t,n=b(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(b.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1))},filter:function(e){return this.pushStack(ft(this,e,!0))},is:function(e){return!!e&&("string"==typeof e?lt.test(e)?b(e,this.context).index(this[0])>=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,o=[],a=lt.test(e)||"string"!=typeof e?b(e,t||this.context):0;for(;i>r;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&11!==n.nodeType){if(a?a.index(n)>-1:b.find.matchesSelector(n,e)){o.push(n);break}n=n.parentNode}}return this.pushStack(o.length>1?b.unique(o):o)},index:function(e){return e?"string"==typeof e?b.inArray(this[0],b(e)):b.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?b(e,t):b.makeArray(e&&e.nodeType?[e]:e),r=b.merge(this.get(),n);return this.pushStack(b.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),b.fn.andSelf=b.fn.addBack;function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}b.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(e,t,n){return b.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(e,t,n){return b.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return b.dir(e,"previousSibling",n)},siblings:function(e){return b.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.merge([],e.childNodes)}},function(e,t){b.fn[e]=function(n,r){var i=b.map(this,t,n);return at.test(e)||(r=n),r&&"string"==typeof r&&(i=b.filter(r,i)),i=this.length>1&&!ct[e]?b.unique(i):i,this.length>1&&st.test(e)&&(i=i.reverse()),this.pushStack(i)}}),b.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),1===t.length?b.find.matchesSelector(t[0],e)?[t[0]]:[]:b.find.matches(e,t)},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!b(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(t=t||0,b.isFunction(t))return b.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return b.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=b.grep(e,function(e){return 1===e.nodeType});if(ut.test(t))return b.filter(t,r,!n);t=b.filter(t,r)}return b.grep(e,function(e){return b.inArray(e,t)>=0===n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/<tbody/i,wt=/<|&#?\w+;/,Tt=/<(?:script|style|link)/i,Nt=/^(?:checkbox|radio)$/i,Ct=/checked\s*(?:[^=]|=\s*.checked.)/i,kt=/^$|\/(?:java|ecma)script/i,Et=/^true\/(.*)/,St=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,At={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:b.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},jt=dt(o),Dt=jt.appendChild(o.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,b.fn.extend({text:function(e){return b.access(this,function(e){return e===t?b.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(b.isFunction(e))return this.each(function(t){b(this).wrapAll(e.call(this,t))});if(this[0]){var t=b(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return b.isFunction(e)?this.each(function(t){b(this).wrapInner(e.call(this,t))}):this.each(function(){var t=b(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=b.isFunction(e);return this.each(function(n){b(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){b.nodeName(this,"body")||b(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.insertBefore(e,this.firstChild)})},before:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=0;for(;null!=(n=this[r]);r++)(!e||b.filter(e,[n]).length>0)&&(t||1!==n.nodeType||b.cleanData(Ot(n)),n.parentNode&&(t&&b.contains(n.ownerDocument,n)&&Mt(Ot(n,"script")),n.parentNode.removeChild(n)));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&b.cleanData(Ot(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&b.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return b.clone(this,e,t)})},html:function(e){return b.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!b.support.htmlSerialize&&mt.test(e)||!b.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(b.cleanData(Ot(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){var t=b.isFunction(e);return t||"string"==typeof e||(e=b(e).not(this).detach()),this.domManip([e],!0,function(e){var t=this.nextSibling,n=this.parentNode;n&&(b(this).remove(),n.insertBefore(e,t))})},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=f.apply([],e);var i,o,a,s,u,l,c=0,p=this.length,d=this,h=p-1,g=e[0],m=b.isFunction(g);if(m||!(1>=p||"string"!=typeof g||b.support.checkClone)&&Ct.test(g))return this.each(function(i){var o=d.eq(i);m&&(e[0]=g.call(this,i,n?o.html():t)),o.domManip(e,n,r)});if(p&&(l=b.buildFragment(e,this[0].ownerDocument,!1,this),i=l.firstChild,1===l.childNodes.length&&(l=i),i)){for(n=n&&b.nodeName(i,"tr"),s=b.map(Ot(l,"script"),Ht),a=s.length;p>c;c++)o=l,c!==h&&(o=b.clone(o,!0,!0),a&&b.merge(s,Ot(o,"script"))),r.call(n&&b.nodeName(this[c],"table")?Lt(this[c],"tbody"):this[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,b.map(s,qt),c=0;a>c;c++)o=s[c],kt.test(o.type||"")&&!b._data(o,"globalEval")&&b.contains(u,o)&&(o.src?b.ajax({url:o.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):b.globalEval((o.text||o.textContent||o.innerHTML||"").replace(St,"")));l=i=null}return this}});function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function Ht(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function Mt(e,t){var n,r=0;for(;null!=(n=e[r]);r++)b._data(n,"globalEval",!t||b._data(t[r],"globalEval"))}function _t(e,t){if(1===t.nodeType&&b.hasData(e)){var n,r,i,o=b._data(e),a=b._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)b.event.add(t,n,s[n][r])}a.data&&(a.data=b.extend({},a.data))}}function Ft(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!b.support.noCloneEvent&&t[b.expando]){i=b._data(t);for(r in i.events)b.removeEvent(t,r,i.handle);t.removeAttribute(b.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),b.support.html5Clone&&e.innerHTML&&!b.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Nt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}b.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){b.fn[e]=function(e){var n,r=0,i=[],o=b(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),b(o[r])[t](n),d.apply(i,n.get());return this.pushStack(i)}});function Ot(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||b.nodeName(o,n)?s.push(o):b.merge(s,Ot(o,n));return n===t||n&&b.nodeName(e,n)?b.merge([e],s):s}function Bt(e){Nt.test(e.type)&&(e.defaultChecked=e.checked)}b.extend({clone:function(e,t,n){var r,i,o,a,s,u=b.contains(e.ownerDocument,e);if(b.support.html5Clone||b.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(b.support.noCloneEvent&&b.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||b.isXMLDoc(e)))for(r=Ot(o),s=Ot(e),a=0;null!=(i=s[a]);++a)r[a]&&Ft(i,r[a]);if(t)if(n)for(s=s||Ot(e),r=r||Ot(o),a=0;null!=(i=s[a]);a++)_t(i,r[a]);else _t(e,o);return r=Ot(o,"script"),r.length>0&&Mt(r,!u&&Ot(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,u,l,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===b.type(o))b.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),u=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[u]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1></$2>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!b.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!b.support.tbody){o="table"!==u||xt.test(o)?"<table>"!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)b.nodeName(l=o.childNodes[i],"tbody")&&!l.childNodes.length&&o.removeChild(l)
+}b.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),b.support.appendChecked||b.grep(Ot(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===b.inArray(o,r))&&(a=b.contains(o.ownerDocument,o),s=Ot(f.appendChild(o),"script"),a&&Mt(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,u=b.expando,l=b.cache,p=b.support.deleteExpando,f=b.event.special;for(;null!=(n=e[s]);s++)if((t||b.acceptData(n))&&(o=n[u],a=o&&l[o])){if(a.events)for(r in a.events)f[r]?b.event.remove(n,r):b.removeEvent(n,r,a.handle);l[o]&&(delete l[o],p?delete n[u]:typeof n.removeAttribute!==i?n.removeAttribute(u):n[u]=null,c.push(o))}}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+x+")(.*)$","i"),Yt=RegExp("^("+x+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+x+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===b.css(e,"display")||!b.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=b._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=b._data(r,"olddisplay",un(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&b._data(r,"olddisplay",i?n:b.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}b.fn.extend({css:function(e,n){return b.access(this,function(e,n,r){var i,o,a={},s=0;if(b.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=b.css(e,n[s],!1,o);return a}return r!==t?b.style(e,n,r):b.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:nn(this))?b(this).show():b(this).hide()})}}),b.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,u=b.camelCase(n),l=e.style;if(n=b.cssProps[u]||(b.cssProps[u]=tn(l,u)),s=b.cssHooks[n]||b.cssHooks[u],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:l[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(b.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||b.cssNumber[u]||(r+="px"),b.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(l[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{l[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,u=b.camelCase(n);return n=b.cssProps[u]||(b.cssProps[u]=tn(e.style,u)),s=b.cssHooks[n]||b.cssHooks[u],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||b.isNumeric(o)?o||0:a):a},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s.getPropertyValue(n)||s[n]:t,l=e.style;return s&&(""!==u||b.contains(e.ownerDocument,e)||(u=b.style(e,n)),Yt.test(u)&&Ut.test(n)&&(i=l.width,o=l.minWidth,a=l.maxWidth,l.minWidth=l.maxWidth=l.width=u,u=s.width,l.width=i,l.minWidth=o,l.maxWidth=a)),u}):o.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s[n]:t,l=e.style;return null==u&&l&&l[n]&&(u=l[n]),Yt.test(u)&&!zt.test(n)&&(i=l.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),l.left="fontSize"===n?"1em":u,u=l.pixelLeft+"px",l.left=i,a&&(o.left=a)),""===u?"auto":u});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=b.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=b.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=b.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=b.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=b.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(b.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function un(e){var t=o,n=Gt[e];return n||(n=ln(e,t),"none"!==n&&n||(Pt=(Pt||b("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(Pt[0].contentWindow||Pt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=ln(e,t),Pt.detach()),Gt[e]=n),n}function ln(e,t){var n=b(t.createElement(e)).appendTo(t.body),r=b.css(n[0],"display");return n.remove(),r}b.each(["height","width"],function(e,n){b.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&Xt.test(b.css(e,"display"))?b.swap(e,Qt,function(){return sn(e,n,i)}):sn(e,n,i):t},set:function(e,t,r){var i=r&&Rt(e);return on(e,t,r?an(e,n,r,b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,i),i):0)}}}),b.support.opacity||(b.cssHooks.opacity={get:function(e,t){return It.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=b.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===b.trim(o.replace($t,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=$t.test(o)?o.replace($t,i):o+" "+i)}}),b(function(){b.support.reliableMarginRight||(b.cssHooks.marginRight={get:function(e,n){return n?b.swap(e,{display:"inline-block"},Wt,[e,"marginRight"]):t}}),!b.support.pixelPosition&&b.fn.position&&b.each(["top","left"],function(e,n){b.cssHooks[n]={get:function(e,r){return r?(r=Wt(e,n),Yt.test(r)?b(e).position()[n]+"px":r):t}}})}),b.expr&&b.expr.filters&&(b.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight||!b.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||b.css(e,"display"))},b.expr.filters.visible=function(e){return!b.expr.filters.hidden(e)}),b.each({margin:"",padding:"",border:"Width"},function(e,t){b.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+Zt[r]+t]=o[r]||o[r-2]||o[0];return i}},Ut.test(e)||(b.cssHooks[e+t].set=on)});var cn=/%20/g,pn=/\[\]$/,fn=/\r?\n/g,dn=/^(?:submit|button|image|reset|file)$/i,hn=/^(?:input|select|textarea|keygen)/i;b.fn.extend({serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=b.prop(this,"elements");return e?b.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!b(this).is(":disabled")&&hn.test(this.nodeName)&&!dn.test(e)&&(this.checked||!Nt.test(e))}).map(function(e,t){var n=b(this).val();return null==n?null:b.isArray(n)?b.map(n,function(e){return{name:t.name,value:e.replace(fn,"\r\n")}}):{name:t.name,value:n.replace(fn,"\r\n")}}).get()}}),b.param=function(e,n){var r,i=[],o=function(e,t){t=b.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=b.ajaxSettings&&b.ajaxSettings.traditional),b.isArray(e)||e.jquery&&!b.isPlainObject(e))b.each(e,function(){o(this.name,this.value)});else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")};function gn(e,t,n,r){var i;if(b.isArray(t))b.each(t,function(t,i){n||pn.test(e)?r(e,i):gn(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==b.type(t))r(e,t);else for(i in t)gn(e+"["+i+"]",t[i],n,r)}b.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){b.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),b.fn.hover=function(e,t){return this.mouseenter(e).mouseleave(t||e)};var mn,yn,vn=b.now(),bn=/\?/,xn=/#.*$/,wn=/([?&])_=[^&]*/,Tn=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Nn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Cn=/^(?:GET|HEAD)$/,kn=/^\/\//,En=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Sn=b.fn.load,An={},jn={},Dn="*/".concat("*");try{yn=a.href}catch(Ln){yn=o.createElement("a"),yn.href="",yn=yn.href}mn=En.exec(yn.toLowerCase())||[];function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(w)||[];if(b.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function qn(e,n,r,i){var o={},a=e===jn;function s(u){var l;return o[u]=!0,b.each(e[u]||[],function(e,u){var c=u(n,r,i);return"string"!=typeof c||a||o[c]?a?!(l=c):t:(n.dataTypes.unshift(c),s(c),!1)}),l}return s(n.dataTypes[0])||!o["*"]&&s("*")}function Mn(e,n){var r,i,o=b.ajaxSettings.flatOptions||{};for(i in n)n[i]!==t&&((o[i]?e:r||(r={}))[i]=n[i]);return r&&b.extend(!0,e,r),e}b.fn.load=function(e,n,r){if("string"!=typeof e&&Sn)return Sn.apply(this,arguments);var i,o,a,s=this,u=e.indexOf(" ");return u>=0&&(i=e.slice(u,e.length),e=e.slice(0,u)),b.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(a="POST"),s.length>0&&b.ajax({url:e,type:a,dataType:"html",data:n}).done(function(e){o=arguments,s.html(i?b("<div>").append(b.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},b.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){b.fn[t]=function(e){return this.on(t,e)}}),b.each(["get","post"],function(e,n){b[n]=function(e,r,i,o){return b.isFunction(r)&&(o=o||i,i=r,r=t),b.ajax({url:e,type:n,dataType:o,data:r,success:i})}}),b.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Nn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Mn(Mn(e,b.ajaxSettings),t):Mn(b.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,u,l,c,p=b.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?b(f):b.event,h=b.Deferred(),g=b.Callbacks("once memory"),m=p.statusCode||{},y={},v={},x=0,T="canceled",N={readyState:0,getResponseHeader:function(e){var t;if(2===x){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===x?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return x||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return x||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>x)for(t in e)m[t]=[m[t],e[t]];else N.always(e[N.status]);return this},abort:function(e){var t=e||T;return l&&l.abort(t),k(0,t),this}};if(h.promise(N).complete=g.add,N.success=N.done,N.error=N.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=b.trim(p.dataType||"*").toLowerCase().match(w)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?80:443))==(mn[3]||("http:"===mn[1]?80:443)))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=b.param(p.data,p.traditional)),qn(An,p,n,N),2===x)return N;u=p.global,u&&0===b.active++&&b.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Cn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(b.lastModified[o]&&N.setRequestHeader("If-Modified-Since",b.lastModified[o]),b.etag[o]&&N.setRequestHeader("If-None-Match",b.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&N.setRequestHeader("Content-Type",p.contentType),N.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)N.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,N,p)===!1||2===x))return N.abort();T="abort";for(i in{success:1,error:1,complete:1})N[i](p[i]);if(l=qn(jn,p,n,N)){N.readyState=1,u&&d.trigger("ajaxSend",[N,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){N.abort("timeout")},p.timeout));try{x=1,l.send(y,k)}catch(C){if(!(2>x))throw C;k(-1,C)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,C=n;2!==x&&(x=2,s&&clearTimeout(s),l=t,a=i||"",N.readyState=e>0?4:0,r&&(w=_n(p,N,r)),e>=200&&300>e||304===e?(p.ifModified&&(T=N.getResponseHeader("Last-Modified"),T&&(b.lastModified[o]=T),T=N.getResponseHeader("etag"),T&&(b.etag[o]=T)),204===e?(c=!0,C="nocontent"):304===e?(c=!0,C="notmodified"):(c=Fn(p,w),C=c.state,y=c.data,v=c.error,c=!v)):(v=C,(e||!C)&&(C="error",0>e&&(e=0))),N.status=e,N.statusText=(n||C)+"",c?h.resolveWith(f,[y,C,N]):h.rejectWith(f,[N,C,v]),N.statusCode(m),m=t,u&&d.trigger(c?"ajaxSuccess":"ajaxError",[N,p,c?y:v]),g.fireWith(f,[N,C]),u&&(d.trigger("ajaxComplete",[N,p]),--b.active||b.event.trigger("ajaxStop")))}return N},getScript:function(e,n){return b.get(e,t,n,"script")},getJSON:function(e,t,n){return b.get(e,t,n,"json")}});function _n(e,n,r){var i,o,a,s,u=e.contents,l=e.dataTypes,c=e.responseFields;for(s in c)s in r&&(n[c[s]]=r[s]);while("*"===l[0])l.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in u)if(u[s]&&u[s].test(o)){l.unshift(s);break}if(l[0]in r)a=l[0];else{for(s in r){if(!l[0]||e.converters[s+" "+l[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==l[0]&&l.unshift(a),r[a]):t}function Fn(e,t){var n,r,i,o,a={},s=0,u=e.dataTypes.slice(),l=u[0];if(e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u[1])for(i in e.converters)a[i.toLowerCase()]=e.converters[i];for(;r=u[++s];)if("*"!==r){if("*"!==l&&l!==r){if(i=a[l+" "+r]||a["* "+r],!i)for(n in a)if(o=n.split(" "),o[1]===r&&(i=a[l+" "+o[0]]||a["* "+o[0]])){i===!0?i=a[n]:a[n]!==!0&&(r=o[0],u.splice(s--,0,r));break}if(i!==!0)if(i&&e["throws"])t=i(t);else try{t=i(t)}catch(c){return{state:"parsererror",error:i?c:"No conversion from "+l+" to "+r}}}l=r}return{state:"success",data:t}}b.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return b.globalEval(e),e}}}),b.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),b.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=o.head||b("head")[0]||o.documentElement;return{send:function(t,i){n=o.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var On=[],Bn=/(=)\?(?=&|$)|\?\?/;b.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=On.pop()||b.expando+"_"+vn++;return this[e]=!0,e}}),b.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,u=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return u||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=b.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,u?n[u]=n[u].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||b.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,On.push(o)),s&&b.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}b.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=b.ajaxSettings.xhr(),b.support.cors=!!Rn&&"withCredentials"in Rn,Rn=b.support.ajax=!!Rn,Rn&&b.ajaxTransport(function(n){if(!n.crossDomain||b.support.cors){var r;return{send:function(i,o){var a,s,u=n.xhr();if(n.username?u.open(n.type,n.url,n.async,n.username,n.password):u.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)u[s]=n.xhrFields[s];n.mimeType&&u.overrideMimeType&&u.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)u.setRequestHeader(s,i[s])}catch(l){}u.send(n.hasContent&&n.data||null),r=function(e,i){var s,l,c,p;try{if(r&&(i||4===u.readyState))if(r=t,a&&(u.onreadystatechange=b.noop,$n&&delete Pn[a]),i)4!==u.readyState&&u.abort();else{p={},s=u.status,l=u.getAllResponseHeaders(),"string"==typeof u.responseText&&(p.text=u.responseText);try{c=u.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,l)},n.async?4===u.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},b(e).unload($n)),Pn[a]=r),u.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+x+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n,r,i=this.createTween(e,t),o=Yn.exec(t),a=i.cur(),s=+a||0,u=1,l=20;if(o){if(n=+o[2],r=o[3]||(b.cssNumber[e]?"":"px"),"px"!==r&&s){s=b.css(i.elem,e,!0)||n||1;do u=u||".5",s/=u,b.style(i.elem,e,s+r);while(u!==(u=i.cur()/a)&&1!==u&&--l)}i.unit=r,i.start=s,i.end=o[1]?s+(o[1]+1)*n:n}return i}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=b.now()}function Zn(e,t){b.each(t,function(t,n){var r=(Qn[t]||[]).concat(Qn["*"]),i=0,o=r.length;for(;o>i;i++)if(r[i].call(e,t,n))return})}function er(e,t,n){var r,i,o=0,a=Gn.length,s=b.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,a=0,u=l.tweens.length;for(;u>a;a++)l.tweens[a].run(o);return s.notifyWith(e,[l,o,n]),1>o&&u?n:(s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:b.extend({},t),opts:b.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=b.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)l.tweens[n].run(1);return t?s.resolveWith(e,[l,t]):s.rejectWith(e,[l,t]),this}}),c=l.props;for(tr(c,l.opts.specialEasing);a>o;o++)if(r=Gn[o].call(l,e,c,l.opts))return r;return Zn(l,c),b.isFunction(l.opts.start)&&l.opts.start.call(e,l),b.fx.timer(b.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function tr(e,t){var n,r,i,o,a;for(i in e)if(r=b.camelCase(i),o=t[r],n=e[i],b.isArray(n)&&(o=n[1],n=e[i]=n[0]),i!==r&&(e[r]=n,delete e[i]),a=b.cssHooks[r],a&&"expand"in a){n=a.expand(n),delete e[r];for(i in n)i in e||(e[i]=n[i],t[i]=o)}else t[r]=o}b.Animation=b.extend(er,{tweener:function(e,t){b.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,u,l,c,p,f=this,d=e.style,h={},g=[],m=e.nodeType&&nn(e);n.queue||(c=b._queueHooks(e,"fx"),null==c.unqueued&&(c.unqueued=0,p=c.empty.fire,c.empty.fire=function(){c.unqueued||p()}),c.unqueued++,f.always(function(){f.always(function(){c.unqueued--,b.queue(e,"fx").length||c.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[d.overflow,d.overflowX,d.overflowY],"inline"===b.css(e,"display")&&"none"===b.css(e,"float")&&(b.support.inlineBlockNeedsLayout&&"inline"!==un(e.nodeName)?d.zoom=1:d.display="inline-block")),n.overflow&&(d.overflow="hidden",b.support.shrinkWrapBlocks||f.always(function(){d.overflow=n.overflow[0],d.overflowX=n.overflow[1],d.overflowY=n.overflow[2]}));for(i in t)if(a=t[i],Vn.exec(a)){if(delete t[i],u=u||"toggle"===a,a===(m?"hide":"show"))continue;g.push(i)}if(o=g.length){s=b._data(e,"fxshow")||b._data(e,"fxshow",{}),"hidden"in s&&(m=s.hidden),u&&(s.hidden=!m),m?b(e).show():f.done(function(){b(e).hide()}),f.done(function(){var t;b._removeData(e,"fxshow");for(t in h)b.style(e,t,h[t])});for(i=0;o>i;i++)r=g[i],l=f.createTween(r,m?s[r]:0),h[r]=s[r]||b.style(e,r),r in s||(s[r]=l.start,m&&(l.end=l.start,l.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}b.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(b.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?b.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=b.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){b.fx.step[e.prop]?b.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[b.cssProps[e.prop]]||b.cssHooks[e.prop])?b.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},b.each(["toggle","show","hide"],function(e,t){var n=b.fn[t];b.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),b.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=b.isEmptyObject(e),o=b.speed(t,n,r),a=function(){var t=er(this,b.extend({},e),o);a.finish=function(){t.stop(!0)},(i||b._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=b.timers,a=b._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&b.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=b._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=b.timers,a=r?r.length:0;for(n.finish=!0,b.queue(this,e,[]),i&&i.cur&&i.cur.finish&&i.cur.finish.call(this),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}b.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){b.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),b.speed=function(e,t,n){var r=e&&"object"==typeof e?b.extend({},e):{complete:n||!n&&t||b.isFunction(e)&&e,duration:e,easing:n&&t||t&&!b.isFunction(t)&&t};return r.duration=b.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in b.fx.speeds?b.fx.speeds[r.duration]:b.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){b.isFunction(r.old)&&r.old.call(this),r.queue&&b.dequeue(this,r.queue)},r},b.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},b.timers=[],b.fx=rr.prototype.init,b.fx.tick=function(){var e,n=b.timers,r=0;for(Xn=b.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||b.fx.stop(),Xn=t},b.fx.timer=function(e){e()&&b.timers.push(e)&&b.fx.start()},b.fx.interval=13,b.fx.start=function(){Un||(Un=setInterval(b.fx.tick,b.fx.interval))},b.fx.stop=function(){clearInterval(Un),Un=null},b.fx.speeds={slow:600,fast:200,_default:400},b.fx.step={},b.expr&&b.expr.filters&&(b.expr.filters.animated=function(e){return b.grep(b.timers,function(t){return e===t.elem}).length}),b.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){b.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,b.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},b.offset={setOffset:function(e,t,n){var r=b.css(e,"position");"static"===r&&(e.style.position="relative");var i=b(e),o=i.offset(),a=b.css(e,"top"),s=b.css(e,"left"),u=("absolute"===r||"fixed"===r)&&b.inArray("auto",[a,s])>-1,l={},c={},p,f;u?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),b.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(l.top=t.top-o.top+p),null!=t.left&&(l.left=t.left-o.left+f),"using"in t?t.using.call(e,l):i.css(l)}},b.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===b.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),b.nodeName(e[0],"html")||(n=e.offset()),n.top+=b.css(e[0],"borderTopWidth",!0),n.left+=b.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-b.css(r,"marginTop",!0),left:t.left-n.left-b.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||o.documentElement;while(e&&!b.nodeName(e,"html")&&"static"===b.css(e,"position"))e=e.offsetParent;return e||o.documentElement})}}),b.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);b.fn[e]=function(i){return b.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?b(a).scrollLeft():o,r?o:b(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return b.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}b.each({Height:"height",Width:"width"},function(e,n){b.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){b.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return b.access(this,function(n,r,i){var o;return b.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?b.css(n,r,s):b.style(n,r,i,s)},n,a?i:t,a,null)}})}),e.jQuery=e.$=b,"function"==typeof define&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return b})})(window);
\ No newline at end of file
diff --git a/sdncon/ui/static/js/thirdparty/jquery-ui-1.10.2.custom.js b/sdncon/ui/static/js/thirdparty/jquery-ui-1.10.2.custom.js
new file mode 100755
index 0000000..8bdb846
--- /dev/null
+++ b/sdncon/ui/static/js/thirdparty/jquery-ui-1.10.2.custom.js
@@ -0,0 +1,1658 @@
+/*! jQuery UI - v1.10.2 - 2013-04-05
+* http://jqueryui.com
+* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.tabs.js
+* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
+
+(function( $, undefined ) {
+
+var uuid = 0,
+	runiqueId = /^ui-id-\d+$/;
+
+// $.ui might exist from components with no dependencies, e.g., $.ui.position
+$.ui = $.ui || {};
+
+$.extend( $.ui, {
+	version: "1.10.2",
+
+	keyCode: {
+		BACKSPACE: 8,
+		COMMA: 188,
+		DELETE: 46,
+		DOWN: 40,
+		END: 35,
+		ENTER: 13,
+		ESCAPE: 27,
+		HOME: 36,
+		LEFT: 37,
+		NUMPAD_ADD: 107,
+		NUMPAD_DECIMAL: 110,
+		NUMPAD_DIVIDE: 111,
+		NUMPAD_ENTER: 108,
+		NUMPAD_MULTIPLY: 106,
+		NUMPAD_SUBTRACT: 109,
+		PAGE_DOWN: 34,
+		PAGE_UP: 33,
+		PERIOD: 190,
+		RIGHT: 39,
+		SPACE: 32,
+		TAB: 9,
+		UP: 38
+	}
+});
+
+// plugins
+$.fn.extend({
+	focus: (function( orig ) {
+		return function( delay, fn ) {
+			return typeof delay === "number" ?
+				this.each(function() {
+					var elem = this;
+					setTimeout(function() {
+						$( elem ).focus();
+						if ( fn ) {
+							fn.call( elem );
+						}
+					}, delay );
+				}) :
+				orig.apply( this, arguments );
+		};
+	})( $.fn.focus ),
+
+	scrollParent: function() {
+		var scrollParent;
+		if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
+			scrollParent = this.parents().filter(function() {
+				return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
+			}).eq(0);
+		} else {
+			scrollParent = this.parents().filter(function() {
+				return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
+			}).eq(0);
+		}
+
+		return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
+	},
+
+	zIndex: function( zIndex ) {
+		if ( zIndex !== undefined ) {
+			return this.css( "zIndex", zIndex );
+		}
+
+		if ( this.length ) {
+			var elem = $( this[ 0 ] ), position, value;
+			while ( elem.length && elem[ 0 ] !== document ) {
+				// Ignore z-index if position is set to a value where z-index is ignored by the browser
+				// This makes behavior of this function consistent across browsers
+				// WebKit always returns auto if the element is positioned
+				position = elem.css( "position" );
+				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
+					// IE returns 0 when zIndex is not specified
+					// other browsers return a string
+					// we ignore the case of nested elements with an explicit value of 0
+					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
+					value = parseInt( elem.css( "zIndex" ), 10 );
+					if ( !isNaN( value ) && value !== 0 ) {
+						return value;
+					}
+				}
+				elem = elem.parent();
+			}
+		}
+
+		return 0;
+	},
+
+	uniqueId: function() {
+		return this.each(function() {
+			if ( !this.id ) {
+				this.id = "ui-id-" + (++uuid);
+			}
+		});
+	},
+
+	removeUniqueId: function() {
+		return this.each(function() {
+			if ( runiqueId.test( this.id ) ) {
+				$( this ).removeAttr( "id" );
+			}
+		});
+	}
+});
+
+// selectors
+function focusable( element, isTabIndexNotNaN ) {
+	var map, mapName, img,
+		nodeName = element.nodeName.toLowerCase();
+	if ( "area" === nodeName ) {
+		map = element.parentNode;
+		mapName = map.name;
+		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
+			return false;
+		}
+		img = $( "img[usemap=#" + mapName + "]" )[0];
+		return !!img && visible( img );
+	}
+	return ( /input|select|textarea|button|object/.test( nodeName ) ?
+		!element.disabled :
+		"a" === nodeName ?
+			element.href || isTabIndexNotNaN :
+			isTabIndexNotNaN) &&
+		// the element and all of its ancestors must be visible
+		visible( element );
+}
+
+function visible( element ) {
+	return $.expr.filters.visible( element ) &&
+		!$( element ).parents().addBack().filter(function() {
+			return $.css( this, "visibility" ) === "hidden";
+		}).length;
+}
+
+$.extend( $.expr[ ":" ], {
+	data: $.expr.createPseudo ?
+		$.expr.createPseudo(function( dataName ) {
+			return function( elem ) {
+				return !!$.data( elem, dataName );
+			};
+		}) :
+		// support: jQuery <1.8
+		function( elem, i, match ) {
+			return !!$.data( elem, match[ 3 ] );
+		},
+
+	focusable: function( element ) {
+		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
+	},
+
+	tabbable: function( element ) {
+		var tabIndex = $.attr( element, "tabindex" ),
+			isTabIndexNaN = isNaN( tabIndex );
+		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
+	}
+});
+
+// support: jQuery <1.8
+if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
+	$.each( [ "Width", "Height" ], function( i, name ) {
+		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
+			type = name.toLowerCase(),
+			orig = {
+				innerWidth: $.fn.innerWidth,
+				innerHeight: $.fn.innerHeight,
+				outerWidth: $.fn.outerWidth,
+				outerHeight: $.fn.outerHeight
+			};
+
+		function reduce( elem, size, border, margin ) {
+			$.each( side, function() {
+				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
+				if ( border ) {
+					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
+				}
+				if ( margin ) {
+					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
+				}
+			});
+			return size;
+		}
+
+		$.fn[ "inner" + name ] = function( size ) {
+			if ( size === undefined ) {
+				return orig[ "inner" + name ].call( this );
+			}
+
+			return this.each(function() {
+				$( this ).css( type, reduce( this, size ) + "px" );
+			});
+		};
+
+		$.fn[ "outer" + name] = function( size, margin ) {
+			if ( typeof size !== "number" ) {
+				return orig[ "outer" + name ].call( this, size );
+			}
+
+			return this.each(function() {
+				$( this).css( type, reduce( this, size, true, margin ) + "px" );
+			});
+		};
+	});
+}
+
+// support: jQuery <1.8
+if ( !$.fn.addBack ) {
+	$.fn.addBack = function( selector ) {
+		return this.add( selector == null ?
+			this.prevObject : this.prevObject.filter( selector )
+		);
+	};
+}
+
+// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
+if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
+	$.fn.removeData = (function( removeData ) {
+		return function( key ) {
+			if ( arguments.length ) {
+				return removeData.call( this, $.camelCase( key ) );
+			} else {
+				return removeData.call( this );
+			}
+		};
+	})( $.fn.removeData );
+}
+
+
+
+
+
+// deprecated
+$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
+
+$.support.selectstart = "onselectstart" in document.createElement( "div" );
+$.fn.extend({
+	disableSelection: function() {
+		return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
+			".ui-disableSelection", function( event ) {
+				event.preventDefault();
+			});
+	},
+
+	enableSelection: function() {
+		return this.unbind( ".ui-disableSelection" );
+	}
+});
+
+$.extend( $.ui, {
+	// $.ui.plugin is deprecated.  Use the proxy pattern instead.
+	plugin: {
+		add: function( module, option, set ) {
+			var i,
+				proto = $.ui[ module ].prototype;
+			for ( i in set ) {
+				proto.plugins[ i ] = proto.plugins[ i ] || [];
+				proto.plugins[ i ].push( [ option, set[ i ] ] );
+			}
+		},
+		call: function( instance, name, args ) {
+			var i,
+				set = instance.plugins[ name ];
+			if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
+				return;
+			}
+
+			for ( i = 0; i < set.length; i++ ) {
+				if ( instance.options[ set[ i ][ 0 ] ] ) {
+					set[ i ][ 1 ].apply( instance.element, args );
+				}
+			}
+		}
+	},
+
+	// only used by resizable
+	hasScroll: function( el, a ) {
+
+		//If overflow is hidden, the element might have extra content, but the user wants to hide it
+		if ( $( el ).css( "overflow" ) === "hidden") {
+			return false;
+		}
+
+		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
+			has = false;
+
+		if ( el[ scroll ] > 0 ) {
+			return true;
+		}
+
+		// TODO: determine which cases actually cause this to happen
+		// if the element doesn't have the scroll set, see if it's possible to
+		// set the scroll
+		el[ scroll ] = 1;
+		has = ( el[ scroll ] > 0 );
+		el[ scroll ] = 0;
+		return has;
+	}
+});
+
+})( jQuery );
+(function( $, undefined ) {
+
+var uuid = 0,
+	slice = Array.prototype.slice,
+	_cleanData = $.cleanData;
+$.cleanData = function( elems ) {
+	for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+		try {
+			$( elem ).triggerHandler( "remove" );
+		// http://bugs.jquery.com/ticket/8235
+		} catch( e ) {}
+	}
+	_cleanData( elems );
+};
+
+$.widget = function( name, base, prototype ) {
+	var fullName, existingConstructor, constructor, basePrototype,
+		// proxiedPrototype allows the provided prototype to remain unmodified
+		// so that it can be used as a mixin for multiple widgets (#8876)
+		proxiedPrototype = {},
+		namespace = name.split( "." )[ 0 ];
+
+	name = name.split( "." )[ 1 ];
+	fullName = namespace + "-" + name;
+
+	if ( !prototype ) {
+		prototype = base;
+		base = $.Widget;
+	}
+
+	// create selector for plugin
+	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
+		return !!$.data( elem, fullName );
+	};
+
+	$[ namespace ] = $[ namespace ] || {};
+	existingConstructor = $[ namespace ][ name ];
+	constructor = $[ namespace ][ name ] = function( options, element ) {
+		// allow instantiation without "new" keyword
+		if ( !this._createWidget ) {
+			return new constructor( options, element );
+		}
+
+		// allow instantiation without initializing for simple inheritance
+		// must use "new" keyword (the code above always passes args)
+		if ( arguments.length ) {
+			this._createWidget( options, element );
+		}
+	};
+	// extend with the existing constructor to carry over any static properties
+	$.extend( constructor, existingConstructor, {
+		version: prototype.version,
+		// copy the object used to create the prototype in case we need to
+		// redefine the widget later
+		_proto: $.extend( {}, prototype ),
+		// track widgets that inherit from this widget in case this widget is
+		// redefined after a widget inherits from it
+		_childConstructors: []
+	});
+
+	basePrototype = new base();
+	// we need to make the options hash a property directly on the new instance
+	// otherwise we'll modify the options hash on the prototype that we're
+	// inheriting from
+	basePrototype.options = $.widget.extend( {}, basePrototype.options );
+	$.each( prototype, function( prop, value ) {
+		if ( !$.isFunction( value ) ) {
+			proxiedPrototype[ prop ] = value;
+			return;
+		}
+		proxiedPrototype[ prop ] = (function() {
+			var _super = function() {
+					return base.prototype[ prop ].apply( this, arguments );
+				},
+				_superApply = function( args ) {
+					return base.prototype[ prop ].apply( this, args );
+				};
+			return function() {
+				var __super = this._super,
+					__superApply = this._superApply,
+					returnValue;
+
+				this._super = _super;
+				this._superApply = _superApply;
+
+				returnValue = value.apply( this, arguments );
+
+				this._super = __super;
+				this._superApply = __superApply;
+
+				return returnValue;
+			};
+		})();
+	});
+	constructor.prototype = $.widget.extend( basePrototype, {
+		// TODO: remove support for widgetEventPrefix
+		// always use the name + a colon as the prefix, e.g., draggable:start
+		// don't prefix for widgets that aren't DOM-based
+		widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
+	}, proxiedPrototype, {
+		constructor: constructor,
+		namespace: namespace,
+		widgetName: name,
+		widgetFullName: fullName
+	});
+
+	// If this widget is being redefined then we need to find all widgets that
+	// are inheriting from it and redefine all of them so that they inherit from
+	// the new version of this widget. We're essentially trying to replace one
+	// level in the prototype chain.
+	if ( existingConstructor ) {
+		$.each( existingConstructor._childConstructors, function( i, child ) {
+			var childPrototype = child.prototype;
+
+			// redefine the child widget using the same prototype that was
+			// originally used, but inherit from the new version of the base
+			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
+		});
+		// remove the list of existing child constructors from the old constructor
+		// so the old child constructors can be garbage collected
+		delete existingConstructor._childConstructors;
+	} else {
+		base._childConstructors.push( constructor );
+	}
+
+	$.widget.bridge( name, constructor );
+};
+
+$.widget.extend = function( target ) {
+	var input = slice.call( arguments, 1 ),
+		inputIndex = 0,
+		inputLength = input.length,
+		key,
+		value;
+	for ( ; inputIndex < inputLength; inputIndex++ ) {
+		for ( key in input[ inputIndex ] ) {
+			value = input[ inputIndex ][ key ];
+			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
+				// Clone objects
+				if ( $.isPlainObject( value ) ) {
+					target[ key ] = $.isPlainObject( target[ key ] ) ?
+						$.widget.extend( {}, target[ key ], value ) :
+						// Don't extend strings, arrays, etc. with objects
+						$.widget.extend( {}, value );
+				// Copy everything else by reference
+				} else {
+					target[ key ] = value;
+				}
+			}
+		}
+	}
+	return target;
+};
+
+$.widget.bridge = function( name, object ) {
+	var fullName = object.prototype.widgetFullName || name;
+	$.fn[ name ] = function( options ) {
+		var isMethodCall = typeof options === "string",
+			args = slice.call( arguments, 1 ),
+			returnValue = this;
+
+		// allow multiple hashes to be passed on init
+		options = !isMethodCall && args.length ?
+			$.widget.extend.apply( null, [ options ].concat(args) ) :
+			options;
+
+		if ( isMethodCall ) {
+			this.each(function() {
+				var methodValue,
+					instance = $.data( this, fullName );
+				if ( !instance ) {
+					return $.error( "cannot call methods on " + name + " prior to initialization; " +
+						"attempted to call method '" + options + "'" );
+				}
+				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
+					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
+				}
+				methodValue = instance[ options ].apply( instance, args );
+				if ( methodValue !== instance && methodValue !== undefined ) {
+					returnValue = methodValue && methodValue.jquery ?
+						returnValue.pushStack( methodValue.get() ) :
+						methodValue;
+					return false;
+				}
+			});
+		} else {
+			this.each(function() {
+				var instance = $.data( this, fullName );
+				if ( instance ) {
+					instance.option( options || {} )._init();
+				} else {
+					$.data( this, fullName, new object( options, this ) );
+				}
+			});
+		}
+
+		return returnValue;
+	};
+};
+
+$.Widget = function( /* options, element */ ) {};
+$.Widget._childConstructors = [];
+
+$.Widget.prototype = {
+	widgetName: "widget",
+	widgetEventPrefix: "",
+	defaultElement: "<div>",
+	options: {
+		disabled: false,
+
+		// callbacks
+		create: null
+	},
+	_createWidget: function( options, element ) {
+		element = $( element || this.defaultElement || this )[ 0 ];
+		this.element = $( element );
+		this.uuid = uuid++;
+		this.eventNamespace = "." + this.widgetName + this.uuid;
+		this.options = $.widget.extend( {},
+			this.options,
+			this._getCreateOptions(),
+			options );
+
+		this.bindings = $();
+		this.hoverable = $();
+		this.focusable = $();
+
+		if ( element !== this ) {
+			$.data( element, this.widgetFullName, this );
+			this._on( true, this.element, {
+				remove: function( event ) {
+					if ( event.target === element ) {
+						this.destroy();
+					}
+				}
+			});
+			this.document = $( element.style ?
+				// element within the document
+				element.ownerDocument :
+				// element is window or document
+				element.document || element );
+			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
+		}
+
+		this._create();
+		this._trigger( "create", null, this._getCreateEventData() );
+		this._init();
+	},
+	_getCreateOptions: $.noop,
+	_getCreateEventData: $.noop,
+	_create: $.noop,
+	_init: $.noop,
+
+	destroy: function() {
+		this._destroy();
+		// we can probably remove the unbind calls in 2.0
+		// all event bindings should go through this._on()
+		this.element
+			.unbind( this.eventNamespace )
+			// 1.9 BC for #7810
+			// TODO remove dual storage
+			.removeData( this.widgetName )
+			.removeData( this.widgetFullName )
+			// support: jquery <1.6.3
+			// http://bugs.jquery.com/ticket/9413
+			.removeData( $.camelCase( this.widgetFullName ) );
+		this.widget()
+			.unbind( this.eventNamespace )
+			.removeAttr( "aria-disabled" )
+			.removeClass(
+				this.widgetFullName + "-disabled " +
+				"ui-state-disabled" );
+
+		// clean up events and states
+		this.bindings.unbind( this.eventNamespace );
+		this.hoverable.removeClass( "ui-state-hover" );
+		this.focusable.removeClass( "ui-state-focus" );
+	},
+	_destroy: $.noop,
+
+	widget: function() {
+		return this.element;
+	},
+
+	option: function( key, value ) {
+		var options = key,
+			parts,
+			curOption,
+			i;
+
+		if ( arguments.length === 0 ) {
+			// don't return a reference to the internal hash
+			return $.widget.extend( {}, this.options );
+		}
+
+		if ( typeof key === "string" ) {
+			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
+			options = {};
+			parts = key.split( "." );
+			key = parts.shift();
+			if ( parts.length ) {
+				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
+				for ( i = 0; i < parts.length - 1; i++ ) {
+					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
+					curOption = curOption[ parts[ i ] ];
+				}
+				key = parts.pop();
+				if ( value === undefined ) {
+					return curOption[ key ] === undefined ? null : curOption[ key ];
+				}
+				curOption[ key ] = value;
+			} else {
+				if ( value === undefined ) {
+					return this.options[ key ] === undefined ? null : this.options[ key ];
+				}
+				options[ key ] = value;
+			}
+		}
+
+		this._setOptions( options );
+
+		return this;
+	},
+	_setOptions: function( options ) {
+		var key;
+
+		for ( key in options ) {
+			this._setOption( key, options[ key ] );
+		}
+
+		return this;
+	},
+	_setOption: function( key, value ) {
+		this.options[ key ] = value;
+
+		if ( key === "disabled" ) {
+			this.widget()
+				.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
+				.attr( "aria-disabled", value );
+			this.hoverable.removeClass( "ui-state-hover" );
+			this.focusable.removeClass( "ui-state-focus" );
+		}
+
+		return this;
+	},
+
+	enable: function() {
+		return this._setOption( "disabled", false );
+	},
+	disable: function() {
+		return this._setOption( "disabled", true );
+	},
+
+	_on: function( suppressDisabledCheck, element, handlers ) {
+		var delegateElement,
+			instance = this;
+
+		// no suppressDisabledCheck flag, shuffle arguments
+		if ( typeof suppressDisabledCheck !== "boolean" ) {
+			handlers = element;
+			element = suppressDisabledCheck;
+			suppressDisabledCheck = false;
+		}
+
+		// no element argument, shuffle and use this.element
+		if ( !handlers ) {
+			handlers = element;
+			element = this.element;
+			delegateElement = this.widget();
+		} else {
+			// accept selectors, DOM elements
+			element = delegateElement = $( element );
+			this.bindings = this.bindings.add( element );
+		}
+
+		$.each( handlers, function( event, handler ) {
+			function handlerProxy() {
+				// allow widgets to customize the disabled handling
+				// - disabled as an array instead of boolean
+				// - disabled class as method for disabling individual parts
+				if ( !suppressDisabledCheck &&
+						( instance.options.disabled === true ||
+							$( this ).hasClass( "ui-state-disabled" ) ) ) {
+					return;
+				}
+				return ( typeof handler === "string" ? instance[ handler ] : handler )
+					.apply( instance, arguments );
+			}
+
+			// copy the guid so direct unbinding works
+			if ( typeof handler !== "string" ) {
+				handlerProxy.guid = handler.guid =
+					handler.guid || handlerProxy.guid || $.guid++;
+			}
+
+			var match = event.match( /^(\w+)\s*(.*)$/ ),
+				eventName = match[1] + instance.eventNamespace,
+				selector = match[2];
+			if ( selector ) {
+				delegateElement.delegate( selector, eventName, handlerProxy );
+			} else {
+				element.bind( eventName, handlerProxy );
+			}
+		});
+	},
+
+	_off: function( element, eventName ) {
+		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
+		element.unbind( eventName ).undelegate( eventName );
+	},
+
+	_delay: function( handler, delay ) {
+		function handlerProxy() {
+			return ( typeof handler === "string" ? instance[ handler ] : handler )
+				.apply( instance, arguments );
+		}
+		var instance = this;
+		return setTimeout( handlerProxy, delay || 0 );
+	},
+
+	_hoverable: function( element ) {
+		this.hoverable = this.hoverable.add( element );
+		this._on( element, {
+			mouseenter: function( event ) {
+				$( event.currentTarget ).addClass( "ui-state-hover" );
+			},
+			mouseleave: function( event ) {
+				$( event.currentTarget ).removeClass( "ui-state-hover" );
+			}
+		});
+	},
+
+	_focusable: function( element ) {
+		this.focusable = this.focusable.add( element );
+		this._on( element, {
+			focusin: function( event ) {
+				$( event.currentTarget ).addClass( "ui-state-focus" );
+			},
+			focusout: function( event ) {
+				$( event.currentTarget ).removeClass( "ui-state-focus" );
+			}
+		});
+	},
+
+	_trigger: function( type, event, data ) {
+		var prop, orig,
+			callback = this.options[ type ];
+
+		data = data || {};
+		event = $.Event( event );
+		event.type = ( type === this.widgetEventPrefix ?
+			type :
+			this.widgetEventPrefix + type ).toLowerCase();
+		// the original event may come from any element
+		// so we need to reset the target on the new event
+		event.target = this.element[ 0 ];
+
+		// copy original event properties over to the new event
+		orig = event.originalEvent;
+		if ( orig ) {
+			for ( prop in orig ) {
+				if ( !( prop in event ) ) {
+					event[ prop ] = orig[ prop ];
+				}
+			}
+		}
+
+		this.element.trigger( event, data );
+		return !( $.isFunction( callback ) &&
+			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
+			event.isDefaultPrevented() );
+	}
+};
+
+$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
+	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
+		if ( typeof options === "string" ) {
+			options = { effect: options };
+		}
+		var hasOptions,
+			effectName = !options ?
+				method :
+				options === true || typeof options === "number" ?
+					defaultEffect :
+					options.effect || defaultEffect;
+		options = options || {};
+		if ( typeof options === "number" ) {
+			options = { duration: options };
+		}
+		hasOptions = !$.isEmptyObject( options );
+		options.complete = callback;
+		if ( options.delay ) {
+			element.delay( options.delay );
+		}
+		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
+			element[ method ]( options );
+		} else if ( effectName !== method && element[ effectName ] ) {
+			element[ effectName ]( options.duration, options.easing, callback );
+		} else {
+			element.queue(function( next ) {
+				$( this )[ method ]();
+				if ( callback ) {
+					callback.call( element[ 0 ] );
+				}
+				next();
+			});
+		}
+	};
+});
+
+})( jQuery );
+(function( $, undefined ) {
+
+var tabId = 0,
+	rhash = /#.*$/;
+
+function getNextTabId() {
+	return ++tabId;
+}
+
+function isLocal( anchor ) {
+	return anchor.hash.length > 1 &&
+		decodeURIComponent( anchor.href.replace( rhash, "" ) ) ===
+			decodeURIComponent( location.href.replace( rhash, "" ) );
+}
+
+$.widget( "ui.tabs", {
+	version: "1.10.2",
+	delay: 300,
+	options: {
+		active: null,
+		collapsible: false,
+		event: "click",
+		heightStyle: "content",
+		hide: null,
+		show: null,
+
+		// callbacks
+		activate: null,
+		beforeActivate: null,
+		beforeLoad: null,
+		load: null
+	},
+
+	_create: function() {
+		var that = this,
+			options = this.options;
+
+		this.running = false;
+
+		this.element
+			.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
+			.toggleClass( "ui-tabs-collapsible", options.collapsible )
+			// Prevent users from focusing disabled tabs via click
+			.delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
+				if ( $( this ).is( ".ui-state-disabled" ) ) {
+					event.preventDefault();
+				}
+			})
+			// support: IE <9
+			// Preventing the default action in mousedown doesn't prevent IE
+			// from focusing the element, so if the anchor gets focused, blur.
+			// We don't have to worry about focusing the previously focused
+			// element since clicking on a non-focusable element should focus
+			// the body anyway.
+			.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
+				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
+					this.blur();
+				}
+			});
+
+		this._processTabs();
+		options.active = this._initialActive();
+
+		// Take disabling tabs via class attribute from HTML
+		// into account and update option properly.
+		if ( $.isArray( options.disabled ) ) {
+			options.disabled = $.unique( options.disabled.concat(
+				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
+					return that.tabs.index( li );
+				})
+			) ).sort();
+		}
+
+		// check for length avoids error when initializing empty list
+		if ( this.options.active !== false && this.anchors.length ) {
+			this.active = this._findActive( options.active );
+		} else {
+			this.active = $();
+		}
+
+		this._refresh();
+
+		if ( this.active.length ) {
+			this.load( options.active );
+		}
+	},
+
+	_initialActive: function() {
+		var active = this.options.active,
+			collapsible = this.options.collapsible,
+			locationHash = location.hash.substring( 1 );
+
+		if ( active === null ) {
+			// check the fragment identifier in the URL
+			if ( locationHash ) {
+				this.tabs.each(function( i, tab ) {
+					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
+						active = i;
+						return false;
+					}
+				});
+			}
+
+			// check for a tab marked active via a class
+			if ( active === null ) {
+				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
+			}
+
+			// no active tab, set to false
+			if ( active === null || active === -1 ) {
+				active = this.tabs.length ? 0 : false;
+			}
+		}
+
+		// handle numbers: negative, out of range
+		if ( active !== false ) {
+			active = this.tabs.index( this.tabs.eq( active ) );
+			if ( active === -1 ) {
+				active = collapsible ? false : 0;
+			}
+		}
+
+		// don't allow collapsible: false and active: false
+		if ( !collapsible && active === false && this.anchors.length ) {
+			active = 0;
+		}
+
+		return active;
+	},
+
+	_getCreateEventData: function() {
+		return {
+			tab: this.active,
+			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
+		};
+	},
+
+	_tabKeydown: function( event ) {
+		/*jshint maxcomplexity:15*/
+		var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
+			selectedIndex = this.tabs.index( focusedTab ),
+			goingForward = true;
+
+		if ( this._handlePageNav( event ) ) {
+			return;
+		}
+
+		switch ( event.keyCode ) {
+			case $.ui.keyCode.RIGHT:
+			case $.ui.keyCode.DOWN:
+				selectedIndex++;
+				break;
+			case $.ui.keyCode.UP:
+			case $.ui.keyCode.LEFT:
+				goingForward = false;
+				selectedIndex--;
+				break;
+			case $.ui.keyCode.END:
+				selectedIndex = this.anchors.length - 1;
+				break;
+			case $.ui.keyCode.HOME:
+				selectedIndex = 0;
+				break;
+			case $.ui.keyCode.SPACE:
+				// Activate only, no collapsing
+				event.preventDefault();
+				clearTimeout( this.activating );
+				this._activate( selectedIndex );
+				return;
+			case $.ui.keyCode.ENTER:
+				// Toggle (cancel delayed activation, allow collapsing)
+				event.preventDefault();
+				clearTimeout( this.activating );
+				// Determine if we should collapse or activate
+				this._activate( selectedIndex === this.options.active ? false : selectedIndex );
+				return;
+			default:
+				return;
+		}
+
+		// Focus the appropriate tab, based on which key was pressed
+		event.preventDefault();
+		clearTimeout( this.activating );
+		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
+
+		// Navigating with control key will prevent automatic activation
+		if ( !event.ctrlKey ) {
+			// Update aria-selected immediately so that AT think the tab is already selected.
+			// Otherwise AT may confuse the user by stating that they need to activate the tab,
+			// but the tab will already be activated by the time the announcement finishes.
+			focusedTab.attr( "aria-selected", "false" );
+			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
+
+			this.activating = this._delay(function() {
+				this.option( "active", selectedIndex );
+			}, this.delay );
+		}
+	},
+
+	_panelKeydown: function( event ) {
+		if ( this._handlePageNav( event ) ) {
+			return;
+		}
+
+		// Ctrl+up moves focus to the current tab
+		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
+			event.preventDefault();
+			this.active.focus();
+		}
+	},
+
+	// Alt+page up/down moves focus to the previous/next tab (and activates)
+	_handlePageNav: function( event ) {
+		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
+			this._activate( this._focusNextTab( this.options.active - 1, false ) );
+			return true;
+		}
+		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
+			this._activate( this._focusNextTab( this.options.active + 1, true ) );
+			return true;
+		}
+	},
+
+	_findNextTab: function( index, goingForward ) {
+		var lastTabIndex = this.tabs.length - 1;
+
+		function constrain() {
+			if ( index > lastTabIndex ) {
+				index = 0;
+			}
+			if ( index < 0 ) {
+				index = lastTabIndex;
+			}
+			return index;
+		}
+
+		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
+			index = goingForward ? index + 1 : index - 1;
+		}
+
+		return index;
+	},
+
+	_focusNextTab: function( index, goingForward ) {
+		index = this._findNextTab( index, goingForward );
+		this.tabs.eq( index ).focus();
+		return index;
+	},
+
+	_setOption: function( key, value ) {
+		if ( key === "active" ) {
+			// _activate() will handle invalid values and update this.options
+			this._activate( value );
+			return;
+		}
+
+		if ( key === "disabled" ) {
+			// don't use the widget factory's disabled handling
+			this._setupDisabled( value );
+			return;
+		}
+
+		this._super( key, value);
+
+		if ( key === "collapsible" ) {
+			this.element.toggleClass( "ui-tabs-collapsible", value );
+			// Setting collapsible: false while collapsed; open first panel
+			if ( !value && this.options.active === false ) {
+				this._activate( 0 );
+			}
+		}
+
+		if ( key === "event" ) {
+			this._setupEvents( value );
+		}
+
+		if ( key === "heightStyle" ) {
+			this._setupHeightStyle( value );
+		}
+	},
+
+	_tabId: function( tab ) {
+		return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
+	},
+
+	_sanitizeSelector: function( hash ) {
+		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
+	},
+
+	refresh: function() {
+		var options = this.options,
+			lis = this.tablist.children( ":has(a[href])" );
+
+		// get disabled tabs from class attribute from HTML
+		// this will get converted to a boolean if needed in _refresh()
+		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
+			return lis.index( tab );
+		});
+
+		this._processTabs();
+
+		// was collapsed or no tabs
+		if ( options.active === false || !this.anchors.length ) {
+			options.active = false;
+			this.active = $();
+		// was active, but active tab is gone
+		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
+			// all remaining tabs are disabled
+			if ( this.tabs.length === options.disabled.length ) {
+				options.active = false;
+				this.active = $();
+			// activate previous tab
+			} else {
+				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
+			}
+		// was active, active tab still exists
+		} else {
+			// make sure active index is correct
+			options.active = this.tabs.index( this.active );
+		}
+
+		this._refresh();
+	},
+
+	_refresh: function() {
+		this._setupDisabled( this.options.disabled );
+		this._setupEvents( this.options.event );
+		this._setupHeightStyle( this.options.heightStyle );
+
+		this.tabs.not( this.active ).attr({
+			"aria-selected": "false",
+			tabIndex: -1
+		});
+		this.panels.not( this._getPanelForTab( this.active ) )
+			.hide()
+			.attr({
+				"aria-expanded": "false",
+				"aria-hidden": "true"
+			});
+
+		// Make sure one tab is in the tab order
+		if ( !this.active.length ) {
+			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
+		} else {
+			this.active
+				.addClass( "ui-tabs-active ui-state-active" )
+				.attr({
+					"aria-selected": "true",
+					tabIndex: 0
+				});
+			this._getPanelForTab( this.active )
+				.show()
+				.attr({
+					"aria-expanded": "true",
+					"aria-hidden": "false"
+				});
+		}
+	},
+
+	_processTabs: function() {
+		var that = this;
+
+		this.tablist = this._getList()
+			.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
+			.attr( "role", "tablist" );
+
+		this.tabs = this.tablist.find( "> li:has(a[href])" )
+			.addClass( "ui-state-default ui-corner-top" )
+			.attr({
+				role: "tab",
+				tabIndex: -1
+			});
+
+		this.anchors = this.tabs.map(function() {
+				return $( "a", this )[ 0 ];
+			})
+			.addClass( "ui-tabs-anchor" )
+			.attr({
+				role: "presentation",
+				tabIndex: -1
+			});
+
+		this.panels = $();
+
+		this.anchors.each(function( i, anchor ) {
+			var selector, panel, panelId,
+				anchorId = $( anchor ).uniqueId().attr( "id" ),
+				tab = $( anchor ).closest( "li" ),
+				originalAriaControls = tab.attr( "aria-controls" );
+
+			// inline tab
+			if ( isLocal( anchor ) ) {
+				selector = anchor.hash;
+				panel = that.element.find( that._sanitizeSelector( selector ) );
+			// remote tab
+			} else {
+				panelId = that._tabId( tab );
+				selector = "#" + panelId;
+				panel = that.element.find( selector );
+				if ( !panel.length ) {
+					panel = that._createPanel( panelId );
+					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
+				}
+				panel.attr( "aria-live", "polite" );
+			}
+
+			if ( panel.length) {
+				that.panels = that.panels.add( panel );
+			}
+			if ( originalAriaControls ) {
+				tab.data( "ui-tabs-aria-controls", originalAriaControls );
+			}
+			tab.attr({
+				"aria-controls": selector.substring( 1 ),
+				"aria-labelledby": anchorId
+			});
+			panel.attr( "aria-labelledby", anchorId );
+		});
+
+		this.panels
+			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
+			.attr( "role", "tabpanel" );
+	},
+
+	// allow overriding how to find the list for rare usage scenarios (#7715)
+	_getList: function() {
+		return this.element.find( "ol,ul" ).eq( 0 );
+	},
+
+	_createPanel: function( id ) {
+		return $( "<div>" )
+			.attr( "id", id )
+			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
+			.data( "ui-tabs-destroy", true );
+	},
+
+	_setupDisabled: function( disabled ) {
+		if ( $.isArray( disabled ) ) {
+			if ( !disabled.length ) {
+				disabled = false;
+			} else if ( disabled.length === this.anchors.length ) {
+				disabled = true;
+			}
+		}
+
+		// disable tabs
+		for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
+			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
+				$( li )
+					.addClass( "ui-state-disabled" )
+					.attr( "aria-disabled", "true" );
+			} else {
+				$( li )
+					.removeClass( "ui-state-disabled" )
+					.removeAttr( "aria-disabled" );
+			}
+		}
+
+		this.options.disabled = disabled;
+	},
+
+	_setupEvents: function( event ) {
+		var events = {
+			click: function( event ) {
+				event.preventDefault();
+			}
+		};
+		if ( event ) {
+			$.each( event.split(" "), function( index, eventName ) {
+				events[ eventName ] = "_eventHandler";
+			});
+		}
+
+		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
+		this._on( this.anchors, events );
+		this._on( this.tabs, { keydown: "_tabKeydown" } );
+		this._on( this.panels, { keydown: "_panelKeydown" } );
+
+		this._focusable( this.tabs );
+		this._hoverable( this.tabs );
+	},
+
+	_setupHeightStyle: function( heightStyle ) {
+		var maxHeight,
+			parent = this.element.parent();
+
+		if ( heightStyle === "fill" ) {
+			maxHeight = parent.height();
+			maxHeight -= this.element.outerHeight() - this.element.height();
+
+			this.element.siblings( ":visible" ).each(function() {
+				var elem = $( this ),
+					position = elem.css( "position" );
+
+				if ( position === "absolute" || position === "fixed" ) {
+					return;
+				}
+				maxHeight -= elem.outerHeight( true );
+			});
+
+			this.element.children().not( this.panels ).each(function() {
+				maxHeight -= $( this ).outerHeight( true );
+			});
+
+			this.panels.each(function() {
+				$( this ).height( Math.max( 0, maxHeight -
+					$( this ).innerHeight() + $( this ).height() ) );
+			})
+			.css( "overflow", "auto" );
+		} else if ( heightStyle === "auto" ) {
+			maxHeight = 0;
+			this.panels.each(function() {
+				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
+			}).height( maxHeight );
+		}
+	},
+
+	_eventHandler: function( event ) {
+		var options = this.options,
+			active = this.active,
+			anchor = $( event.currentTarget ),
+			tab = anchor.closest( "li" ),
+			clickedIsActive = tab[ 0 ] === active[ 0 ],
+			collapsing = clickedIsActive && options.collapsible,
+			toShow = collapsing ? $() : this._getPanelForTab( tab ),
+			toHide = !active.length ? $() : this._getPanelForTab( active ),
+			eventData = {
+				oldTab: active,
+				oldPanel: toHide,
+				newTab: collapsing ? $() : tab,
+				newPanel: toShow
+			};
+
+		event.preventDefault();
+
+		if ( tab.hasClass( "ui-state-disabled" ) ||
+				// tab is already loading
+				tab.hasClass( "ui-tabs-loading" ) ||
+				// can't switch durning an animation
+				this.running ||
+				// click on active header, but not collapsible
+				( clickedIsActive && !options.collapsible ) ||
+				// allow canceling activation
+				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
+			return;
+		}
+
+		options.active = collapsing ? false : this.tabs.index( tab );
+
+		this.active = clickedIsActive ? $() : tab;
+		if ( this.xhr ) {
+			this.xhr.abort();
+		}
+
+		if ( !toHide.length && !toShow.length ) {
+			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
+		}
+
+		if ( toShow.length ) {
+			this.load( this.tabs.index( tab ), event );
+		}
+		this._toggle( event, eventData );
+	},
+
+	// handles show/hide for selecting tabs
+	_toggle: function( event, eventData ) {
+		var that = this,
+			toShow = eventData.newPanel,
+			toHide = eventData.oldPanel;
+
+		this.running = true;
+
+		function complete() {
+			that.running = false;
+			that._trigger( "activate", event, eventData );
+		}
+
+		function show() {
+			eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
+
+			if ( toShow.length && that.options.show ) {
+				that._show( toShow, that.options.show, complete );
+			} else {
+				toShow.show();
+				complete();
+			}
+		}
+
+		// start out by hiding, then showing, then completing
+		if ( toHide.length && this.options.hide ) {
+			this._hide( toHide, this.options.hide, function() {
+				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
+				show();
+			});
+		} else {
+			eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
+			toHide.hide();
+			show();
+		}
+
+		toHide.attr({
+			"aria-expanded": "false",
+			"aria-hidden": "true"
+		});
+		eventData.oldTab.attr( "aria-selected", "false" );
+		// If we're switching tabs, remove the old tab from the tab order.
+		// If we're opening from collapsed state, remove the previous tab from the tab order.
+		// If we're collapsing, then keep the collapsing tab in the tab order.
+		if ( toShow.length && toHide.length ) {
+			eventData.oldTab.attr( "tabIndex", -1 );
+		} else if ( toShow.length ) {
+			this.tabs.filter(function() {
+				return $( this ).attr( "tabIndex" ) === 0;
+			})
+			.attr( "tabIndex", -1 );
+		}
+
+		toShow.attr({
+			"aria-expanded": "true",
+			"aria-hidden": "false"
+		});
+		eventData.newTab.attr({
+			"aria-selected": "true",
+			tabIndex: 0
+		});
+	},
+
+	_activate: function( index ) {
+		var anchor,
+			active = this._findActive( index );
+
+		// trying to activate the already active panel
+		if ( active[ 0 ] === this.active[ 0 ] ) {
+			return;
+		}
+
+		// trying to collapse, simulate a click on the current active header
+		if ( !active.length ) {
+			active = this.active;
+		}
+
+		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
+		this._eventHandler({
+			target: anchor,
+			currentTarget: anchor,
+			preventDefault: $.noop
+		});
+	},
+
+	_findActive: function( index ) {
+		return index === false ? $() : this.tabs.eq( index );
+	},
+
+	_getIndex: function( index ) {
+		// meta-function to give users option to provide a href string instead of a numerical index.
+		if ( typeof index === "string" ) {
+			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
+		}
+
+		return index;
+	},
+
+	_destroy: function() {
+		if ( this.xhr ) {
+			this.xhr.abort();
+		}
+
+		this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
+
+		this.tablist
+			.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
+			.removeAttr( "role" );
+
+		this.anchors
+			.removeClass( "ui-tabs-anchor" )
+			.removeAttr( "role" )
+			.removeAttr( "tabIndex" )
+			.removeUniqueId();
+
+		this.tabs.add( this.panels ).each(function() {
+			if ( $.data( this, "ui-tabs-destroy" ) ) {
+				$( this ).remove();
+			} else {
+				$( this )
+					.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
+						"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
+					.removeAttr( "tabIndex" )
+					.removeAttr( "aria-live" )
+					.removeAttr( "aria-busy" )
+					.removeAttr( "aria-selected" )
+					.removeAttr( "aria-labelledby" )
+					.removeAttr( "aria-hidden" )
+					.removeAttr( "aria-expanded" )
+					.removeAttr( "role" );
+			}
+		});
+
+		this.tabs.each(function() {
+			var li = $( this ),
+				prev = li.data( "ui-tabs-aria-controls" );
+			if ( prev ) {
+				li
+					.attr( "aria-controls", prev )
+					.removeData( "ui-tabs-aria-controls" );
+			} else {
+				li.removeAttr( "aria-controls" );
+			}
+		});
+
+		this.panels.show();
+
+		if ( this.options.heightStyle !== "content" ) {
+			this.panels.css( "height", "" );
+		}
+	},
+
+	enable: function( index ) {
+		var disabled = this.options.disabled;
+		if ( disabled === false ) {
+			return;
+		}
+
+		if ( index === undefined ) {
+			disabled = false;
+		} else {
+			index = this._getIndex( index );
+			if ( $.isArray( disabled ) ) {
+				disabled = $.map( disabled, function( num ) {
+					return num !== index ? num : null;
+				});
+			} else {
+				disabled = $.map( this.tabs, function( li, num ) {
+					return num !== index ? num : null;
+				});
+			}
+		}
+		this._setupDisabled( disabled );
+	},
+
+	disable: function( index ) {
+		var disabled = this.options.disabled;
+		if ( disabled === true ) {
+			return;
+		}
+
+		if ( index === undefined ) {
+			disabled = true;
+		} else {
+			index = this._getIndex( index );
+			if ( $.inArray( index, disabled ) !== -1 ) {
+				return;
+			}
+			if ( $.isArray( disabled ) ) {
+				disabled = $.merge( [ index ], disabled ).sort();
+			} else {
+				disabled = [ index ];
+			}
+		}
+		this._setupDisabled( disabled );
+	},
+
+	load: function( index, event ) {
+		index = this._getIndex( index );
+		var that = this,
+			tab = this.tabs.eq( index ),
+			anchor = tab.find( ".ui-tabs-anchor" ),
+			panel = this._getPanelForTab( tab ),
+			eventData = {
+				tab: tab,
+				panel: panel
+			};
+
+		// not remote
+		if ( isLocal( anchor[ 0 ] ) ) {
+			return;
+		}
+
+		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
+
+		// support: jQuery <1.8
+		// jQuery <1.8 returns false if the request is canceled in beforeSend,
+		// but as of 1.8, $.ajax() always returns a jqXHR object.
+		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
+			tab.addClass( "ui-tabs-loading" );
+			panel.attr( "aria-busy", "true" );
+
+			this.xhr
+				.success(function( response ) {
+					// support: jQuery <1.8
+					// http://bugs.jquery.com/ticket/11778
+					setTimeout(function() {
+						panel.html( response );
+						that._trigger( "load", event, eventData );
+					}, 1 );
+				})
+				.complete(function( jqXHR, status ) {
+					// support: jQuery <1.8
+					// http://bugs.jquery.com/ticket/11778
+					setTimeout(function() {
+						if ( status === "abort" ) {
+							that.panels.stop( false, true );
+						}
+
+						tab.removeClass( "ui-tabs-loading" );
+						panel.removeAttr( "aria-busy" );
+
+						if ( jqXHR === that.xhr ) {
+							delete that.xhr;
+						}
+					}, 1 );
+				});
+		}
+	},
+
+	_ajaxSettings: function( anchor, event, eventData ) {
+		var that = this;
+		return {
+			url: anchor.attr( "href" ),
+			beforeSend: function( jqXHR, settings ) {
+				return that._trigger( "beforeLoad", event,
+					$.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
+			}
+		};
+	},
+
+	_getPanelForTab: function( tab ) {
+		var id = $( tab ).attr( "aria-controls" );
+		return this.element.find( this._sanitizeSelector( "#" + id ) );
+	}
+});
+
+})( jQuery );
diff --git a/sdncon/ui/static/js/thirdparty/jquery-ui-1.10.2.custom.min.js b/sdncon/ui/static/js/thirdparty/jquery-ui-1.10.2.custom.min.js
new file mode 100755
index 0000000..af3ec73
--- /dev/null
+++ b/sdncon/ui/static/js/thirdparty/jquery-ui-1.10.2.custom.min.js
@@ -0,0 +1,6 @@
+/*! jQuery UI - v1.10.2 - 2013-04-05
+* http://jqueryui.com
+* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.tabs.js
+* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
+
+(function(e,t){function i(t,i){var a,n,r,o=t.nodeName.toLowerCase();return"area"===o?(a=t.parentNode,n=a.name,t.href&&n&&"map"===a.nodeName.toLowerCase()?(r=e("img[usemap=#"+n+"]")[0],!!r&&s(r)):!1):(/input|select|textarea|button|object/.test(o)?!t.disabled:"a"===o?t.href||i:i)&&s(t)}function s(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}var a=0,n=/^ui-id-\d+$/;e.ui=e.ui||{},e.extend(e.ui,{version:"1.10.2",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({focus:function(t){return function(i,s){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),s&&s.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),scrollParent:function(){var t;return t=e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(i){if(i!==t)return this.css("zIndex",i);if(this.length)for(var s,a,n=e(this[0]);n.length&&n[0]!==document;){if(s=n.css("position"),("absolute"===s||"relative"===s||"fixed"===s)&&(a=parseInt(n.css("zIndex"),10),!isNaN(a)&&0!==a))return a;n=n.parent()}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++a)})},removeUniqueId:function(){return this.each(function(){n.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,s){return!!e.data(t,s[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var s=e.attr(t,"tabindex"),a=isNaN(s);return(a||s>=0)&&i(t,!a)}}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(i,s){function a(t,i,s,a){return e.each(n,function(){i-=parseFloat(e.css(t,"padding"+this))||0,s&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),a&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var n="Width"===s?["Left","Right"]:["Top","Bottom"],r=s.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+s]=function(i){return i===t?o["inner"+s].call(this):this.each(function(){e(this).css(r,a(this,i)+"px")})},e.fn["outer"+s]=function(t,i){return"number"!=typeof t?o["outer"+s].call(this,t):this.each(function(){e(this).css(r,a(this,t,!0,i)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.support.selectstart="onselectstart"in document.createElement("div"),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,i,s){var a,n=e.ui[t].prototype;for(a in s)n.plugins[a]=n.plugins[a]||[],n.plugins[a].push([i,s[a]])},call:function(e,t,i){var s,a=e.plugins[t];if(a&&e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType)for(s=0;a.length>s;s++)e.options[a[s][0]]&&a[s][1].apply(e.element,i)}},hasScroll:function(t,i){if("hidden"===e(t).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",a=!1;return t[s]>0?!0:(t[s]=1,a=t[s]>0,t[s]=0,a)}})})(jQuery);(function(e,t){var i=0,s=Array.prototype.slice,n=e.cleanData;e.cleanData=function(t){for(var i,s=0;null!=(i=t[s]);s++)try{e(i).triggerHandler("remove")}catch(a){}n(t)},e.widget=function(i,s,n){var a,r,o,h,l={},u=i.split(".")[0];i=i.split(".")[1],a=u+"-"+i,n||(n=s,s=e.Widget),e.expr[":"][a.toLowerCase()]=function(t){return!!e.data(t,a)},e[u]=e[u]||{},r=e[u][i],o=e[u][i]=function(e,i){return this._createWidget?(arguments.length&&this._createWidget(e,i),t):new o(e,i)},e.extend(o,r,{version:n.version,_proto:e.extend({},n),_childConstructors:[]}),h=new s,h.options=e.widget.extend({},h.options),e.each(n,function(i,n){return e.isFunction(n)?(l[i]=function(){var e=function(){return s.prototype[i].apply(this,arguments)},t=function(e){return s.prototype[i].apply(this,e)};return function(){var i,s=this._super,a=this._superApply;return this._super=e,this._superApply=t,i=n.apply(this,arguments),this._super=s,this._superApply=a,i}}(),t):(l[i]=n,t)}),o.prototype=e.widget.extend(h,{widgetEventPrefix:r?h.widgetEventPrefix:i},l,{constructor:o,namespace:u,widgetName:i,widgetFullName:a}),r?(e.each(r._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete r._childConstructors):s._childConstructors.push(o),e.widget.bridge(i,o)},e.widget.extend=function(i){for(var n,a,r=s.call(arguments,1),o=0,h=r.length;h>o;o++)for(n in r[o])a=r[o][n],r[o].hasOwnProperty(n)&&a!==t&&(i[n]=e.isPlainObject(a)?e.isPlainObject(i[n])?e.widget.extend({},i[n],a):e.widget.extend({},a):a);return i},e.widget.bridge=function(i,n){var a=n.prototype.widgetFullName||i;e.fn[i]=function(r){var o="string"==typeof r,h=s.call(arguments,1),l=this;return r=!o&&h.length?e.widget.extend.apply(null,[r].concat(h)):r,o?this.each(function(){var s,n=e.data(this,a);return n?e.isFunction(n[r])&&"_"!==r.charAt(0)?(s=n[r].apply(n,h),s!==n&&s!==t?(l=s&&s.jquery?l.pushStack(s.get()):s,!1):t):e.error("no such method '"+r+"' for "+i+" widget instance"):e.error("cannot call methods on "+i+" prior to initialization; "+"attempted to call method '"+r+"'")}):this.each(function(){var t=e.data(this,a);t?t.option(r||{})._init():e.data(this,a,new n(r,this))}),l}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(t,s){s=e(s||this.defaultElement||this)[0],this.element=e(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),s!==this&&(e.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===s&&this.destroy()}}),this.document=e(s.style?s.ownerDocument:s.document||s),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(i,s){var n,a,r,o=i;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof i)if(o={},n=i.split("."),i=n.shift(),n.length){for(a=o[i]=e.widget.extend({},this.options[i]),r=0;n.length-1>r;r++)a[n[r]]=a[n[r]]||{},a=a[n[r]];if(i=n.pop(),s===t)return a[i]===t?null:a[i];a[i]=s}else{if(s===t)return this.options[i]===t?null:this.options[i];o[i]=s}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!t).attr("aria-disabled",t),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(i,s,n){var a,r=this;"boolean"!=typeof i&&(n=s,s=i,i=!1),n?(s=a=e(s),this.bindings=this.bindings.add(s)):(n=s,s=this.element,a=this.widget()),e.each(n,function(n,o){function h(){return i||r.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?r[o]:o).apply(r,arguments):t}"string"!=typeof o&&(h.guid=o.guid=o.guid||h.guid||e.guid++);var l=n.match(/^(\w+)\s*(.*)$/),u=l[1]+r.eventNamespace,c=l[2];c?a.delegate(c,u,h):s.bind(u,h)})},_off:function(e,t){t=(t||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.unbind(t).undelegate(t)},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var n,a,r=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],a=i.originalEvent)for(n in a)n in i||(i[n]=a[n]);return this.element.trigger(i,s),!(e.isFunction(r)&&r.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,n,a){"string"==typeof n&&(n={effect:n});var r,o=n?n===!0||"number"==typeof n?i:n.effect||i:t;n=n||{},"number"==typeof n&&(n={duration:n}),r=!e.isEmptyObject(n),n.complete=a,n.delay&&s.delay(n.delay),r&&e.effects&&e.effects.effect[o]?s[t](n):o!==t&&s[o]?s[o](n.duration,n.easing,a):s.queue(function(i){e(this)[t](),a&&a.call(s[0]),i()})}})})(jQuery);(function(t,e){function i(){return++n}function s(t){return t.hash.length>1&&decodeURIComponent(t.href.replace(a,""))===decodeURIComponent(location.href.replace(a,""))}var n=0,a=/#.*$/;t.widget("ui.tabs",{version:"1.10.2",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var e=this,i=this.options;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",i.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(e){t(this).is(".ui-state-disabled")&&e.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){t(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs(),i.active=this._initialActive(),t.isArray(i.disabled)&&(i.disabled=t.unique(i.disabled.concat(t.map(this.tabs.filter(".ui-state-disabled"),function(t){return e.tabs.index(t)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):t(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var i=this.options.active,s=this.options.collapsible,n=location.hash.substring(1);return null===i&&(n&&this.tabs.each(function(s,a){return t(a).attr("aria-controls")===n?(i=s,!1):e}),null===i&&(i=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===i||-1===i)&&(i=this.tabs.length?0:!1)),i!==!1&&(i=this.tabs.index(this.tabs.eq(i)),-1===i&&(i=s?!1:0)),!s&&i===!1&&this.anchors.length&&(i=0),i},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):t()}},_tabKeydown:function(i){var s=t(this.document[0].activeElement).closest("li"),n=this.tabs.index(s),a=!0;if(!this._handlePageNav(i)){switch(i.keyCode){case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:n++;break;case t.ui.keyCode.UP:case t.ui.keyCode.LEFT:a=!1,n--;break;case t.ui.keyCode.END:n=this.anchors.length-1;break;case t.ui.keyCode.HOME:n=0;break;case t.ui.keyCode.SPACE:return i.preventDefault(),clearTimeout(this.activating),this._activate(n),e;case t.ui.keyCode.ENTER:return i.preventDefault(),clearTimeout(this.activating),this._activate(n===this.options.active?!1:n),e;default:return}i.preventDefault(),clearTimeout(this.activating),n=this._focusNextTab(n,a),i.ctrlKey||(s.attr("aria-selected","false"),this.tabs.eq(n).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",n)},this.delay))}},_panelKeydown:function(e){this._handlePageNav(e)||e.ctrlKey&&e.keyCode===t.ui.keyCode.UP&&(e.preventDefault(),this.active.focus())},_handlePageNav:function(i){return i.altKey&&i.keyCode===t.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):i.altKey&&i.keyCode===t.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):e},_findNextTab:function(e,i){function s(){return e>n&&(e=0),0>e&&(e=n),e}for(var n=this.tabs.length-1;-1!==t.inArray(s(),this.options.disabled);)e=i?e+1:e-1;return e},_focusNextTab:function(t,e){return t=this._findNextTab(t,e),this.tabs.eq(t).focus(),t},_setOption:function(t,i){return"active"===t?(this._activate(i),e):"disabled"===t?(this._setupDisabled(i),e):(this._super(t,i),"collapsible"===t&&(this.element.toggleClass("ui-tabs-collapsible",i),i||this.options.active!==!1||this._activate(0)),"event"===t&&this._setupEvents(i),"heightStyle"===t&&this._setupHeightStyle(i),e)},_tabId:function(t){return t.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(t){return t?t.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var e=this.options,i=this.tablist.children(":has(a[href])");e.disabled=t.map(i.filter(".ui-state-disabled"),function(t){return i.index(t)}),this._processTabs(),e.active!==!1&&this.anchors.length?this.active.length&&!t.contains(this.tablist[0],this.active[0])?this.tabs.length===e.disabled.length?(e.active=!1,this.active=t()):this._activate(this._findNextTab(Math.max(0,e.active-1),!1)):e.active=this.tabs.index(this.active):(e.active=!1,this.active=t()),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var e=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return t("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=t(),this.anchors.each(function(i,n){var a,o,r,h=t(n).uniqueId().attr("id"),l=t(n).closest("li"),u=l.attr("aria-controls");s(n)?(a=n.hash,o=e.element.find(e._sanitizeSelector(a))):(r=e._tabId(l),a="#"+r,o=e.element.find(a),o.length||(o=e._createPanel(r),o.insertAfter(e.panels[i-1]||e.tablist)),o.attr("aria-live","polite")),o.length&&(e.panels=e.panels.add(o)),u&&l.data("ui-tabs-aria-controls",u),l.attr({"aria-controls":a.substring(1),"aria-labelledby":h}),o.attr("aria-labelledby",h)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(e){return t("<div>").attr("id",e).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(e){t.isArray(e)&&(e.length?e.length===this.anchors.length&&(e=!0):e=!1);for(var i,s=0;i=this.tabs[s];s++)e===!0||-1!==t.inArray(s,e)?t(i).addClass("ui-state-disabled").attr("aria-disabled","true"):t(i).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=e},_setupEvents:function(e){var i={click:function(t){t.preventDefault()}};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(e){var i,s=this.element.parent();"fill"===e?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=t(this).outerHeight(!0)}),this.panels.each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.panels.each(function(){i=Math.max(i,t(this).height("").height())}).height(i))},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),a=n.closest("li"),o=a[0]===s[0],r=o&&i.collapsible,h=r?t():this._getPanelForTab(a),l=s.length?this._getPanelForTab(s):t(),u={oldTab:s,oldPanel:l,newTab:r?t():a,newPanel:h};e.preventDefault(),a.hasClass("ui-state-disabled")||a.hasClass("ui-tabs-loading")||this.running||o&&!i.collapsible||this._trigger("beforeActivate",e,u)===!1||(i.active=r?!1:this.tabs.index(a),this.active=o?t():a,this.xhr&&this.xhr.abort(),l.length||h.length||t.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(a),e),this._toggle(e,u))},_toggle:function(e,i){function s(){a.running=!1,a._trigger("activate",e,i)}function n(){i.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),o.length&&a.options.show?a._show(o,a.options.show,s):(o.show(),s())}var a=this,o=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),n()}):(i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),r.hide(),n()),r.attr({"aria-expanded":"false","aria-hidden":"true"}),i.oldTab.attr("aria-selected","false"),o.length&&r.length?i.oldTab.attr("tabIndex",-1):o.length&&this.tabs.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),o.attr({"aria-expanded":"true","aria-hidden":"false"}),i.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(e){var i,s=this._findActive(e);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return e===!1?t():this.tabs.eq(e)},_getIndex:function(t){return"string"==typeof t&&(t=this.anchors.index(this.anchors.filter("[href$='"+t+"']"))),t},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){t.data(this,"ui-tabs-destroy")?t(this).remove():t(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var e=t(this),i=e.data("ui-tabs-aria-controls");i?e.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):e.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(i){var s=this.options.disabled;s!==!1&&(i===e?s=!1:(i=this._getIndex(i),s=t.isArray(s)?t.map(s,function(t){return t!==i?t:null}):t.map(this.tabs,function(t,e){return e!==i?e:null})),this._setupDisabled(s))},disable:function(i){var s=this.options.disabled;if(s!==!0){if(i===e)s=!0;else{if(i=this._getIndex(i),-1!==t.inArray(i,s))return;s=t.isArray(s)?t.merge([i],s).sort():[i]}this._setupDisabled(s)}},load:function(e,i){e=this._getIndex(e);var n=this,a=this.tabs.eq(e),o=a.find(".ui-tabs-anchor"),r=this._getPanelForTab(a),h={tab:a,panel:r};s(o[0])||(this.xhr=t.ajax(this._ajaxSettings(o,i,h)),this.xhr&&"canceled"!==this.xhr.statusText&&(a.addClass("ui-tabs-loading"),r.attr("aria-busy","true"),this.xhr.success(function(t){setTimeout(function(){r.html(t),n._trigger("load",i,h)},1)}).complete(function(t,e){setTimeout(function(){"abort"===e&&n.panels.stop(!1,!0),a.removeClass("ui-tabs-loading"),r.removeAttr("aria-busy"),t===n.xhr&&delete n.xhr},1)})))},_ajaxSettings:function(e,i,s){var n=this;return{url:e.attr("href"),beforeSend:function(e,a){return n._trigger("beforeLoad",i,t.extend({jqXHR:e,ajaxSettings:a},s))}}},_getPanelForTab:function(e){var i=t(e).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}})})(jQuery);
\ No newline at end of file
diff --git a/sdncon/ui/static/js/topology.js b/sdncon/ui/static/js/topology.js
new file mode 100755
index 0000000..7ebfc43
--- /dev/null
+++ b/sdncon/ui/static/js/topology.js
@@ -0,0 +1,192 @@
+/*
+Copyright (c) 2013 Sencha Inc. - Author: Nicolas Garcia Belmonte (http://philogb.github.com/)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+ */
+/*
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+*/
+
+//
+// ForceDirected example1.js Javascript
+//
+// Slightly modified for use in rendering a simple network diagram topology
+//
+
+var labelType, useGradients, nativeTextSupport, animate;
+
+(function() {
+  var ua = navigator.userAgent,
+      iStuff = ua.match(/iPhone/i) || ua.match(/iPad/i),
+      typeOfCanvas = typeof HTMLCanvasElement,
+      nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'),
+      textSupport = nativeCanvasSupport 
+        && (typeof document.createElement('canvas').getContext('2d').fillText == 'function');
+  //I'm setting this based on the fact that ExCanvas provides text support for IE
+  //and that as of today iPhone/iPad current text support is lame
+  labelType = (!nativeCanvasSupport || (textSupport && !iStuff))? 'Native' : 'HTML';
+  nativeTextSupport = labelType == 'Native';
+  useGradients = nativeCanvasSupport;
+  animate = !(iStuff || !nativeCanvasSupport);
+})();
+
+var Log = {
+  elem: false,
+  write: function(text){
+    if (!this.elem) 
+      this.elem = document.getElementById('log');
+    this.elem.innerHTML = text;
+    this.elem.style.left = (500 - this.elem.offsetWidth / 2) + 'px';
+  }
+};
+
+
+  // init data
+   var json = loadTopologyJSON();
+  // end
+  // init ForceDirected
+   var fd = new $jit.ForceDirected({
+    //id of the visualization container
+    injectInto: 'infovis',
+    //force height
+    height: 900,
+    //Enable zooming and panning
+    //by scrolling and DnD
+    Navigation: {
+      enable: true,
+      //Enable panning events only if we're dragging the empty
+      //canvas (and not a node).
+      panning: 'avoid nodes',
+      zooming: 10 //zoom speed. higher is more sensible
+    },
+    // Change node and edge styles such as
+    // color and width.
+    // These properties are also set per node
+    // with dollar prefixed data-properties in the
+    // JSON structure.
+    Node: {
+      overridable: true
+    },
+    Edge: {
+      overridable: true,
+      color: '#23A4FF',
+      lineWidth: 0.4
+    },
+    //Native canvas text styling
+    Label: {
+      type: labelType, //Native or HTML
+      size: 10,
+      color: '#000000',
+      style: 'bold'
+    },
+    //Add Tips
+    Tips: {
+      enable: true,
+      onShow: function(tip, node) {
+        if(!node) return;
+        // Build the relations list as a tooltip.
+        // This is done by traversing the clicked node connections.
+        var html = "<div class=\"dynamictable2\"> <table> <tr><td>" + node.name + " links:</td></tr><tr><td>",
+            list = [];
+        node.eachAdjacency(function(adj){
+          list.push(adj.nodeTo.name);
+        });
+        //append connections information
+        tip.innerHTML = html + list.join("</td></tr><tr><td>") + "</td></tr></table></div>";
+      }
+    },
+    // Add node events
+    Events: {
+      enable: true,
+      type: 'Native',
+      //Change cursor style when hovering a node
+      onMouseEnter: function() {
+        fd.canvas.getElement().style.cursor = 'move';
+      },
+      onMouseLeave: function() {
+        fd.canvas.getElement().style.cursor = '';
+      },
+      //Update node positions when dragged
+      onDragMove: function(node, eventInfo, e) {
+          var pos = eventInfo.getPos();
+          node.pos.setc(pos.x, pos.y);
+          fd.plot();
+      },
+      //Implement the same handler for touchscreens
+      onTouchMove: function(node, eventInfo, e) {
+        $jit.util.event.stop(e); //stop default touchmove event
+        this.onDragMove(node, eventInfo, e);
+      },
+      //No node click-handler for now
+      //onClick: function(node) {
+      //}
+    },
+    //Number of iterations for the FD algorithm
+    iterations: 10,
+    //Edge length
+    levelDistance: 130,
+    // Add text to the labels. This method is only triggered
+    // on label creation and only for DOM labels (not native canvas ones).
+    onCreateLabel: function(domElement, node){
+      domElement.innerHTML = node.name;
+      var style = domElement.style;
+      style.fontSize = "0.8em";
+      style.color = "#ddd";
+    },
+    // Change node styles when DOM labels are placed
+    // or moved.
+    onPlaceLabel: function(domElement, node){
+      var style = domElement.style;
+      var left = parseInt(style.left);
+      var top = parseInt(style.top);
+      var w = domElement.offsetWidth;
+      style.left = (left - w / 2) + 'px';
+      style.top = (top + 10) + 'px';
+      style.display = '';
+    }
+  });
+  // load JSON data.
+  fd.loadJSON(json);
+  // compute positions incrementally and animate.
+  fd.computeIncremental({
+    iter: 40,
+    property: 'end',
+    onStep: function(perc){
+      Log.write(perc + '% loaded...');
+    },
+    onComplete: function(){
+      Log.write('done');
+    }
+  });
+  // end
diff --git a/sdncon/ui/templates/base.html b/sdncon/ui/templates/base.html
new file mode 100755
index 0000000..04e58a1
--- /dev/null
+++ b/sdncon/ui/templates/base.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head> 
+		<link rel="shortcut icon" href="static/favicon.ico" type="image/vnd.microsoft.icon">
+		<link href="static/css/thirdparty/jquery-ui-1.10.2.custom.css" rel="stylesheet">
+		<title>Open Daylight SDN Controller Platform Dashboard</title>
+		<link type="text/css" rel="stylesheet" href="static/css/table.css" media="all">
+    </head>
+
+	<body>
+				{% block content %}
+				{% endblock %}
+	</body>
+</html>
\ No newline at end of file
diff --git a/sdncon/ui/templates/index.html b/sdncon/ui/templates/index.html
new file mode 100755
index 0000000..50f63b5
--- /dev/null
+++ b/sdncon/ui/templates/index.html
@@ -0,0 +1,184 @@
+<!-- 
+
+ Copyright (c) 2013 Big Switch Networks, Inc.
+
+ Licensed under the Eclipse Public License, Version 1.0 (the
+ "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+      http://www.eclipse.org/legal/epl-v10.html
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ Web UI home
+
+-->
+
+{% extends "base.html" %}
+{% block content %}
+
+		<div id="skip-link">
+		</div>
+		<div id="page">
+			<header id="header" role="banner">
+			<div class="page-width"><div class="page-width-inner clearfix">
+					<div id="site-logo" style="margin: 15px; display: table;">
+						<div style="float: left; width: 100%;">
+							<img src="static/images/logo_opendaylight.png" border="0" style="margin: 0px; padding: 5px;">
+						</div>
+						<div style="float: left;">
+							<span class="title header-processed" id="page-title" style="color: #3f3f40; font-family: sans-serif, Arial Unicode MS, Arial; font-weight: 100; font-size: 40px; margin-bottom: 0px; margin-top: 0px; height: 40px; display: table-cell; vertical-align: middle; width: 100%; position: static; padding-left: 30px;">SDN Controller Platform Dashboard</span>
+						</div>
+					</div>
+					<div id="tagline">
+						<div class="region region-tagline">
+							<div id="block-block-9" class="block block-block first last odd">
+								<div class="block-content clearfix">
+								</div>
+							</div>
+						</div>
+					</div>
+
+			</div></div>
+			</header>
+			<div id="main" class="clearfix">
+				<div class="page-width"><div class="page-width-inner clearfix" style="margin:50px; margin-top: 0px;">
+						<a id="main-content"></a> 
+						<div id="tabs">
+							<ul>
+								<li><a href="#tabs-1">Switches</a></li>
+								<li><a href="#tabs-2">Inter-Switch Links</a></li>
+								<li><a href="#tabs-3">Hosts</a></li>
+								<li><a href="#tabs-4">Tunnels</a></li>
+								<li><a href="#tabs-5">Topology</a></li>
+								<span class="refresh" onClick="refreshTable(99);" style="float: right; padding: .6em; position: relative; z-index:1;"><img src="images/refresh.png" border="0"></span>
+							</ul>
+							<div id="tabs-1">
+								<div id="switchTableHolder" class="dynamictable">
+								</div>
+							</div>
+							<div style="clear: both;"></div>
+							<div id="tabs-2">
+								<div id="linkTableHolder" class="dynamictable">
+								</div>
+							</div>
+							<div style="clear: both;"></div>
+							<div id="tabs-3">
+								<div id="deviceTableHolder" class="dynamictable">
+								</div>
+							</div>
+							<div id="tabs-4">
+								<div id="tunnelTableHolder" class="dynamictable">
+								</div>
+							</div>
+							<div style="clear: both;"></div>
+							<div id="tabs-5">
+								<div id="TopologyTableHolder" class="dynamictable" style="border: 1px #e5e5e5;">
+									<div id="container">
+										<div id="center-container" style="background-color: #e5e5e5; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px;">
+											<div id="infovis"></div>    
+										</div>
+										<div id="log" style="display: none;"></div>
+									</div>
+								</div>
+								<div style="text-align: justify; -ms-text-justify: distribute-all-lines; text-justify: distribute-all-lines;">
+
+									<div style="width: 100%; display: inline-block"></div>
+
+								</div>
+
+								<div style="clear: both;"></div>
+
+							</div>
+
+							<!-- Main content inner-->
+
+						</div>
+				</div></div>
+				<footer id="footer" role="contentinfo">
+				<div class="page-width"><div class="page-width-inner clearfix">  <div class="region region-footer">
+							<div id="block-p6-helper-footer" class="block block-p6-helper first last odd">
+
+
+								<div class="block-content clearfix">
+									<span id="ui-footer-statement" style="font-family: Helvetica, Arial, sans-serif; font-size: 11px; padding-left: 45;"><center>&nbsp; &#169;2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.</center></span>  </div>
+							</div>
+						</div>
+				</div></div>
+				</footer>
+
+				<div id="dumpingground" style="display: none;"></div> 
+
+
+				<!-- /#page -->
+                <script src="static/js/thirdparty/jit.js"></script>
+                <script src="static/js/thirdparty/jquery-1.9.1.min.js"></script>  
+                <script src="static/js/thirdparty/jquery-ui-1.10.2.custom.min.js"></script>
+				<script type="text/javascript">
+
+					$(document).ready(function(){
+							refreshTable(99);
+							});
+$(function() {
+		$( "#tabs" ).tabs({
+activate: function( event, ui ) { refreshTable(ui.newTab.id); }
+});
+		// Hover states on the static widgets
+		$( "#dialog-link, #icons li" ).hover(
+			function() {
+			$( this ).addClass( "ui-state-hover" );
+			},
+			function() {
+			$( this ).removeClass( "ui-state-hover" );
+			}
+			);
+		});
+
+
+function refreshTable(choice){
+	switch(choice) {
+		case 0:
+			$('#switchTableHolder').load('ui/show_switch');
+			break;
+		case 1:
+			$('#linkTableHolder').load('ui/show_link');
+			break;
+		case 2:
+			$('#deviceTableHolder').load('ui/show_host');
+			break;
+		case 3:
+			$('#tunnelTableHolder').load('ui/show_tunnel');
+			break;
+		case 4:
+			var tmpJSON = loadTopologyJSON();
+			fd.loadJSON(tmpJSON);
+			fd.refresh();
+			break;
+		default:
+			$('#switchTableHolder').load('ui/show_switch');
+			$('#linkTableHolder').load('ui/show_link');
+			$('#deviceTableHolder').load('ui/show_host');
+			$('#tunnelTableHolder').load('ui/show_tunnel');
+			var tmpJSON = loadTopologyJSON();
+			fd.loadJSON(tmpJSON);
+			fd.refresh();
+			break;
+	}
+	//setTimeout(refreshTable, 5000);
+}
+    function loadTopologyJSON(){
+        var request = new XMLHttpRequest( );
+        request.open("GET", "ui/build_topology", false);
+        request.send(null);
+        var jsonFILE = request.response;
+        eval(jsonFILE);
+        return(json);
+    }
+    </script>
+<script language="javascript" type="text/javascript" src="static/js/topology.js"></script>
+
+{% endblock %}
diff --git a/sdncon/ui/test.py b/sdncon/ui/test.py
new file mode 100755
index 0000000..888d07b
--- /dev/null
+++ b/sdncon/ui/test.py
@@ -0,0 +1,12 @@
+from showswitch import show_switch_data
+import json, urllib2
+
+def main():
+    request = None
+    print show_switch_data(None)
+
+    #url = 'http://localhost:8000/rest/v1/model/switch-alias/'
+    #print json.load(urllib2.urlopen(url))
+
+if __name__ == "__main__":
+    main()
\ No newline at end of file
diff --git a/sdncon/ui/views.py b/sdncon/ui/views.py
new file mode 100755
index 0000000..3b7a911
--- /dev/null
+++ b/sdncon/ui/views.py
@@ -0,0 +1,66 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+#  Views for the web UI
+#
+
+from django.shortcuts import render_to_response, render
+from django.utils import simplejson
+from django.http import HttpResponse
+from django.contrib.auth.decorators import login_required
+from django.contrib.auth.models import User
+from django.template import RequestContext
+from django.template.loader import render_to_string
+from sdncon.apploader import AppLoader, AppLister
+from sdncon.clusterAdmin.utils import conditionally, isCloudBuild
+from sdncon.clusterAdmin.models import Customer, Cluster, CustomerUser
+from scripts.showswitch import show_switch_data
+from scripts.buildtopology import build_topology_data
+from scripts.showlink import show_link_data
+from scripts.showtunnel import show_tunnel_data
+from scripts.showhost import show_host_data
+import os
+
+
+JSON_CONTENT_TYPE = 'application/json'
+
+# --- View for the root page of any application
+def index(request):
+    return render_to_response('ui/templates/index.html')
+
+def show_switch(request):
+    html = show_switch_data(request)
+    return HttpResponse(html)
+
+def show_link(request):
+    html = show_link_data(request)
+    return HttpResponse(html)
+
+def show_host(request):
+    html = show_host_data(request)
+    return HttpResponse(html)
+
+def show_tunnel(request):
+    html = show_tunnel_data(request)
+    return HttpResponse(html)
+
+
+def build_topology(request):
+    html = build_topology_data(request)
+    return HttpResponse(html)
+
+
+   
diff --git a/sdncon/urls.py b/sdncon/urls.py
new file mode 100755
index 0000000..8478eab
--- /dev/null
+++ b/sdncon/urls.py
@@ -0,0 +1,180 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+import django.views.generic.simple, os, coreui.models
+from django.conf.urls.defaults import *
+from django.contrib import admin
+from apploader import AppLoader
+
+admin.autodiscover()
+
+urlpatterns = patterns('',
+    # Example:
+    # (r'^sdncon/', include('sdncon.foo.urls')),
+
+    # Uncomment the admin/doc line below and add 'django.contrib.admindocs' 
+    # to INSTALLED_APPS to enable admin documentation:
+    #(r'^admin/doc/', include('django.contrib.admindocs.urls')),
+
+    ###################################
+    # Views for the web UI
+    ###################################
+    (r'^$', 'sdncon.ui.views.index'),
+    (r'ui/show_switch', 'sdncon.ui.views.show_switch'),
+    (r'ui/show_host', 'sdncon.ui.views.show_host'),
+    (r'ui/show_link', 'sdncon.ui.views.show_link'),
+    (r'ui/show_tunnel', 'sdncon.ui.views.show_tunnel'),
+    (r'ui/build_topology', 'sdncon.ui.views.build_topology'),
+    # Uncomment the next line to enable the admin:
+    (r'^admin/', include(admin.site.urls)),
+    (r'accounts/login/$', 'django.contrib.auth.views.login'),
+    (r'logout/$', 'django.contrib.auth.views.logout'),
+    (r'password_change/$', 'django.contrib.auth.views.password_change'),
+    (r'password_change_done/$', 'django.contrib.auth.views.password_change_done'),
+    (r'token/?$', 'sdncon.clusterAdmin.views.token_view'),
+    (r'token_generate/?$', 'sdncon.clusterAdmin.views.token_generate'),
+
+    ###################################
+    # Views that implement the REST API
+    ###################################
+    (r'^rest/v1/data/?$', 'sdncon.rest.views.do_user_data_list'),
+    (r'^rest/v1/data/(?P<name>[A-Za-z0-9_:./=;\-]+)/$', 'sdncon.rest.views.do_user_data'),
+
+    # APIs to get tenant info and build type
+    (r'^rest/v1/customer/?$', 'sdncon.clusterAdmin.views.session_clusterAdmin'),
+    (r'^rest/v1/personality/?$', 'sdncon.clusterAdmin.views.get_node_personality'),
+
+    # REST API to access statistics counters from sdnplatform
+    (r'^rest/v1/realtimestats/counter/categories/(?P<dpid>[A-Za-z0-9_:.\-]+)/(?P<stattype>[A-Za-z0-9_:.\-]+)/(?P<layer>[0-9])/?$', 'sdncon.rest.views.do_sdnplatform_counter_categories'),
+    (r'^rest/v1/realtimestats/counter/(?P<stattype>[A-Za-z0-9_:.\-]+)/?$', 'sdncon.rest.views.do_sdnplatform_realtimestats'),
+    (r'^rest/v1/realtimestats/counter/(?P<dpid>[A-Za-z0-9_:.\-]+)/(?P<stattype>[A-Za-z]+)/?$', 'sdncon.rest.views.do_sdnplatform_realtimestats'),
+    (r'^rest/v1/realtimestats/table/(?P<tabletype>[A-Za-z]+)/flow/(?P<dpid>[A-Za-z0-9_:./\-]+)/?$', 'sdncon.rest.views.do_tablerealtimestats'),
+    (r'^rest/v1/realtimestats/group/(?P<groupId>[0-9]+)/(?P<dpid>[A-Za-z0-9_:./\-]+)/?$', 'sdncon.rest.views.do_realtimegroupstats'),
+    (r'^rest/v1/realtimestats/(?P<stattype>[A-Za-z]+)/(?P<dpid>[A-Za-z0-9_:./\-]+)/?$', 'sdncon.rest.views.do_realtimestats'),
+    (r'^rest/v1/controller/stats/(?P<stattype>[A-Za-z]+)/?$', 'sdncon.rest.views.do_controller_stats'),
+    (r'^rest/v1/controller/storage/tables/?$', 'sdncon.rest.views.do_controller_storage_table_list'),
+    
+
+    # REST API VNS/device information
+    (r'^rest/v1/device', 'sdncon.rest.views.do_device'),
+    (r'^rest/v1/switches', 'sdncon.rest.views.do_switches'),
+    (r'^rest/v1/routers', 'sdncon.rest.views.do_routers'),
+    (r'^rest/v1/router/(?P<dpid>[A-Za-z0-9_:.\-]+)/(?P<stattype>[A-Za-z]+)', 'sdncon.rest.views.do_router_stats'),
+    (r'^rest/v1/links', 'sdncon.rest.views.do_links'),
+    (r'^rest/v1/mastership', 'sdncon.rest.views.do_mastership'),
+    (r'^rest/v1/vns/device-interface', 'sdncon.rest.views.do_vns_device_interface'),
+    (r'^rest/v1/vns/interface', 'sdncon.rest.views.do_vns_interface'),
+    (r'^rest/v1/vns/realtimestats/flow/(?P<vnsName>[A-Za-z0-9_:.|\-]+)/?$', 'sdncon.rest.views.do_vns_realtimestats_flow', {'category': 'vns'}),
+    (r'^rest/v1/vns', 'sdncon.rest.views.do_vns'),
+
+    # REST API to access realtime status from sdnplatform
+    (r'^rest/v1/realtimestatus/network/tunnelstatus/all/all/?$', 'sdncon.rest.views.do_topology_tunnel_status'),
+    (r'^rest/v1/realtimestatus/network/tunnelstatus/(?P<srcdpid>[A-Za-z0-9_:.\-]+)/(?P<dstdpid>[A-Za-z0-9_:.\-]+)/?$', 'sdncon.rest.views.do_topology_tunnel_status'),
+    (r'^rest/v1/realtimestatus/network/tunnelverify/(?P<srcdpid>[A-Za-z0-9_:.\-]+)/(?P<dstdpid>[A-Za-z0-9_:.\-]+)/?$', 'sdncon.rest.views.do_topology_tunnel_verify'),
+    (r'^rest/v1/realtimestatus/network/(?P<subcategory>[A-Za-z0-9_:.\-]+)/?$', 'sdncon.rest.views.do_sdnplatform_realtimestatus', {'category': 'network'}),
+
+    # REST API for testing with Explain Packet in realtime
+    (r'^rest/v1/realtimetest/network/(?P<subcategory>[A-Za-z0-9_:.\-]+)/?$', 'sdncon.rest.views.do_sdnplatform_realtimetest', {'category': 'network'}),
+    
+    # REST API for accessing controller system information
+    (r'^rest/v1/system/version/?$', 'sdncon.rest.views.do_system_version', {}),
+    (r'^rest/v1/system/interfaces/?$', 'sdncon.rest.views.do_system_inet4_interfaces', {}),
+    (r'^rest/v1/system/uptime/?$', 'sdncon.rest.views.do_system_uptime', {}),
+    (r'^rest/v1/system/clock/utc/?$', 'sdncon.rest.views.do_system_clock', {'local': False}),
+    (r'^rest/v1/system/clock/local/?$', 'sdncon.rest.views.do_system_clock', {'local': True}),
+    (r'^rest/v1/system/timezones/(?P<list_type>[A-Za-z0-9_\-]+)/?$', 'sdncon.rest.views.do_system_time_zone_strings'),
+    (r'^rest/v1/system/controller/?$', 'sdncon.rest.views.do_controller'),
+    (r'^rest/v1/system/ha/role/?$', 'sdncon.rest.views.do_local_ha_role'),
+    (r'^rest/v1/system/ha/failback/?$', 'sdncon.rest.views.do_ha_failback'),
+    (r'^rest/v1/system/ha/provision/?$', 'sdncon.rest.views.do_ha_provision'),
+    (r'^rest/v1/system/ha/clustername/?$', 'sdncon.rest.views.do_clustername'),
+    (r'^rest/v1/system/ha/decommission/?$', 'sdncon.rest.views.do_decommission'),
+    (r'^rest/v1/system/ha/decommission-internal/?$', 'sdncon.rest.views.do_decommission_internal'),
+    (r'^rest/v1/system/check-config/?$', 'sdncon.rest.views.do_check_config'),
+    (r'^rest/v1/system/reload/?$', 'sdncon.rest.views.do_reload'),
+    (r'^rest/v1/system/resetbsc/?$', 'sdncon.rest.views.do_resetbsc'),
+    (r'^rest/v1/system/delete-images-passwd/?$', 'sdncon.rest.views.do_delete_images_passwd'),
+    (r'^rest/v1/system/upload-data/?$', 'sdncon.rest.views.do_upload_data'),
+    (r'^rest/v1/system/log/$', 'sdncon.rest.views.do_system_log_list'),
+    (r'^rest/v1/system/log/(?P<log_name>[A-Za-z0-9_\-]+)$', 'sdncon.rest.views.do_system_log'),
+    
+    # REST API for upgrades
+    (r'^rest/v1/system/upgrade/extract-image-manifest/?$', 'sdncon.rest.views.do_extract_upgrade_pkg_manifest'),
+    (r'^rest/v1/system/upgrade/image-name/?$', 'sdncon.rest.views.do_get_upgrade_pkg'),
+    (r'^rest/v1/system/upgrade/execute-upgrade-step/?$', 'sdncon.rest.views.do_execute_upgrade_step'),
+    (r'^rest/v1/system/upgrade/cleanup-old-images/?$', 'sdncon.rest.views.do_cleanup_old_pkgs'),
+    (r'^rest/v1/system/upgrade/abort/?$', 'sdncon.rest.views.do_abort_upgrade'),
+   
+     # REST API for config rollback
+    (r'^rest/v1/system/rollback/config/?$', 'sdncon.rest.views.do_config_rollback'),
+    (r'^rest/v1/system/rollback/diffconfig/?$', 'sdncon.rest.views.do_diff_config'),
+
+    # Views for the stats REST API
+    (r'^rest/v1/stats/metadata/(?P<cluster>[A-Za-z0-9_:.\-]+)(/(?P<stats_type>[A-Za-z0-9_\-]+))?/?$', 'sdncon.stats.views.do_get_stats_metadata'),
+    (r'^rest/v1/stats/index/(?P<cluster>[A-Za-z0-9_:.\-]+)/(?P<target_type>[A-Za-z0-9_\-]+)/(?P<target_id>[A-Za-z0-9_\:\.\-]+)(/(?P<stats_type>[A-Za-z0-9_\-]+))?/?$', 'sdncon.stats.views.do_get_stats_type_index'),
+    (r'^rest/v1/stats/target/(?P<cluster>[A-Za-z0-9_:.\-]+)/?$', 'sdncon.stats.views.do_get_stats_target_types'),
+    (r'^rest/v1/stats/target/(?P<cluster>[A-Za-z0-9_:.\-]+)/(?P<target_type>[A-Za-z0-9_\-]+)/?$', 'sdncon.stats.views.do_get_stats_targets'),
+    (r'^rest/v1/stats/data/(?P<cluster>[A-Za-z0-9_:.\-]+)/(?P<target_type>[A-Za-z0-9_\-]+)/(?P<target_id>[A-Za-z0-9_\:\.\-]+)/(?P<stats_type>[A-Za-z0-9_\-]+)/?$', 'sdncon.stats.views.do_get_stats'),
+    (r'^rest/v1/stats/data/(?P<cluster>[A-Za-z0-9_:.\-]+)/?$', 'sdncon.stats.views.do_put_stats'),
+    (r'^rest/v1/events/data/(?P<cluster>[A-Za-z0-9_:.\-]+)/(?P<node_id>[A-Za-z0-9_\.\-]+)/?$', 'sdncon.stats.views.do_get_events'),
+    (r'^rest/v1/events/data/(?P<cluster>[A-Za-z0-9_:.\-]+)/?$', 'sdncon.stats.views.do_put_events'),
+    
+    # Views for the models
+    (r'^rest/v1/model/(?P<model_name>[A-Za-z0-9_\-]+)(/(?P<id>[A-Za-z0-9_:.\-|]+))?/?$', 'sdncon.rest.views.do_instance'),
+    # Get the model list
+    (r'^rest/v1/model/?$', 'sdncon.rest.views.do_model_list'),
+
+    # Views for the synthesized table
+    (r'^rest/v1/synthetic/(?P<model_name>[A-Za-z0-9_\-]+)(/(?P<id>[A-Za-z0-9_:.\-|]+))?/?$', 'sdncon.rest.views.do_synthetic_instance'),
+
+
+    # REST API for packet tracing
+    (r'^rest/v1/packettrace/?$', 'sdncon.rest.views.do_packettrace'),
+
+    # Views for the coreui (base layout and javascript)
+    (r'^coreui/static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': os.path.join(os.path.dirname(__file__)+'/coreui','static')}),
+    (r'^coreui/img/(?P<path>.*)$', 'django.views.static.serve', {'document_root': os.path.join(os.path.dirname(__file__)+'/coreui','img')}),
+
+    # REST APIs for Performance Monitoring information of SDNPlatform and SDNPlatform
+    (r'^rest/v1/performance-monitor/(?P<type>[A-Za-z0-9_.\-]+)/?$', 'sdncon.rest.views.do_sdnplatform_performance_monitor', {'category':'performance-monitor'}),
+
+    # REST APIs for Internal debugging information of SDNPlatform and SDNPlatform
+    (r'^rest/v1/internal-debugs/(?P<component>[A-Za-z0-9\-]+)/(?P<query>[A-Za-z0-9=:\-]+)?/?$', 'sdncon.rest.views.do_sdnplatform_internal_debugs', {'category':'internal-debugs'}),
+
+    # REST APIs for Event History from SDNPlatform and SDNPlatform
+    (r'^rest/v1/event-history/(?P<evHistName>[A-Za-z0-9\-]+)/(?P<count>[0-9]+)?/?$', 'sdncon.rest.views.do_sdnplatform_event_history', {'category':'event-history'}),
+
+    # REST APIs for displaying the content of Flow Cache in real-time
+    # applName = Application Name (e.g. vns)
+    # applInstName = Application Instance Name (e.g. name of the vns or "all")
+    (r'^rest/v1/flow-cache/(?P<applName>[A-Za-z0-9\-]+)/(?P<applInstName>[A-Za-z0-9:.|\-]+)/(?P<queryType>[A-Za-z0-9\-]+)?/?$', 'sdncon.rest.views.do_flow_cache', {'category':'flow-cache'}),
+    #(r'^rest/v1/flow-cache/(?P<applName>[A-Za-z0-9\-]+)/(?P<applInstName>[A-Za-z0-9:.|\-]+)/(?P<queryType>[A-Za-z0-9\-]+)?/?$', 'sdncon.rest.views.do_local', { 'url' : [ 'flow-cache' ], }),
+
+    # REST APIs for Tunnel manager state from SDNPlatform
+    (r'^rest/v1/tunnel-manager/(?P<dpid>[A-Za-z0-9_:.\-]+)/?$', 'sdncon.rest.views.do_sdnplatform_tunnel_manager'),
+
+    # REST APIs for controller summary statistics 
+    (r'^rest/v1/controller/summary$', 'sdncon.rest.views.do_sdnplatform_controller_summary'),
+    
+    # REST APIs for SR tunnel 
+    (r'^rest/v1/tunnel/?$', 'sdncon.rest.views.do_sdnplatform_tunnel_config'),
+    (r'^rest/v1/showtunnel/?$', 'sdncon.rest.views.do_show_tunnel'),
+    # REST APIs for SR policy 
+    (r'^rest/v1/showpolicy/?$', 'sdncon.rest.views.do_show_policy'),
+    (r'^rest/v1/policy/?$', 'sdncon.rest.views.do_sdnplatform_policy_config'),
+
+)
+
