Use Page Speed to minify Web resources at build time, and a few more improvements to the offline support.

git-svn-id: https://svn.apache.org/repos/asf/tuscany/sca-cpp/trunk@1189069 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/.gitignore b/.gitignore
index 93663ee..0a161b3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -58,6 +58,9 @@
 config.status
 *config.js
 all.js
+*-min.html
+*-min.js
+*-min.css
 intro*.png
 intro*.b64
 depcomp
diff --git a/configure.ac b/configure.ac
index 116a71d..3413bc2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -405,6 +405,45 @@
   AM_CONDITIONAL([WANT_PYTHON], false)
 fi
 
+# Configure path to Page Speed.
+AC_MSG_CHECKING([for pagespeed])
+AC_ARG_WITH([pagespeed], [AC_HELP_STRING([--with-pagespeed=PATH], [path to installed Page Speed [default=/usr/bin]])], [
+  PAGESPEED_PREFIX="${withval}"
+  AC_MSG_RESULT("${withval}")
+], [
+  PAGESPEED_PREFIX="/usr/bin"
+  AC_MSG_RESULT(/usr/bin)
+])
+AC_SUBST(PAGESPEED_PREFIX)
+
+# Enable Page Speed optimizations.
+AC_MSG_CHECKING([whether to run Page Speed optimizations])
+AC_ARG_ENABLE(pagespeed, [AS_HELP_STRING([--enable-pagespeed], [run Page Speed optimizations [default=no]])],
+[ case "${enableval}" in
+  no)
+    AC_MSG_RESULT(no)
+    ;;
+  *)
+    AC_MSG_RESULT(yes)
+    want_pagespeed=true
+    ;;
+  esac ],
+[ AC_MSG_RESULT(no)])
+if test "${want_pagespeed}" = "true"; then
+    AC_PATH_PROG(MINIFY_HTML, minify_html_bin, , ${PAGESPEED_PREFIX})
+    if test "${MINIFY_HTML}" = ""; then
+      AC_MSG_ERROR([could not find Page Speed minify_html_bin])
+    fi
+    AC_PATH_PROG(MINIFY_JS, jsmin_bin, , ${PAGESPEED_PREFIX})
+    if test "${MINIFY_JS}" = ""; then
+      AC_MSG_ERROR([could not find Page Speed jsmin_bin])
+    fi
+  AM_CONDITIONAL([WANT_PAGESPEED], true)
+  AC_DEFINE([WANT_PAGESPEED], 1, [run Page Speed optimizations])
+else
+  AM_CONDITIONAL([WANT_PAGESPEED], false)
+fi
+
 # Enable OpenCL support.
 AC_MSG_CHECKING([whether to enable OpenCL support])
 AC_ARG_ENABLE(opencl, [AS_HELP_STRING([--enable-opencl], [enable OpenCL support [default=no]])],
diff --git a/macos/macos-install b/macos/macos-install
index 4c0f868..6072997 100755
--- a/macos/macos-install
+++ b/macos/macos-install
@@ -285,6 +285,16 @@
 fi
 cd $build
 
+# Build Google Page Speed
+curl -OL https://dl-ssl.google.com/page-speed/sdk/current/page-speed-sdk.zip
+unzip page-speed-sdk.zip
+cd page-speed-1.9
+make builddir=$build/page-speed-1.9-bin
+if [ "$?" != "0" ]; then
+    exit $?
+fi
+cd $build
+
 # Build Apache Nuvem
 git clone git://git.apache.org/nuvem.git
 if [ "$?" != "0" ]; then
@@ -296,7 +306,7 @@
 git clone git://git.apache.org/tuscany-sca-cpp.git
 cd tuscany-sca-cpp
 ./bootstrap
-./configure --prefix=$build/tuscany-sca-cpp-bin --with-curl=$build/curl-7.19.5-bin --with-apr=$build/apr-1.4.x-bin --with-httpd=$build/httpd-2.3.10-bin --with-memcached=$build/memcached-1.4.7-bin --with-tinycdb=$build/tinycdb-bin --with-leveldb=$build/leveldb --with-js-include=$build/js-1.8.5-bin/include/js --with-js-lib=$build/js-1.8.5-bin/lib --with-libcloud=$build/libcloud-0.4.2-bin --enable-threads --enable-python --enable-opencl --with-libxml2=$build/libxml2-2.7.7-bin --enable-chat --with-libstrophe=$build/libstrophe-bin --enable-openid --with-mod-auth-openid=$build/mod-auth-openid-bin --enable-oauth --with-liboauth=$build/liboauth-0.9.1-bin --enable-mod-security --with-mod-security=$build/modsecurity-apache-2.6.1-bin
+./configure --prefix=$build/tuscany-sca-cpp-bin --with-curl=$build/curl-7.19.5-bin --with-apr=$build/apr-1.4.x-bin --with-httpd=$build/httpd-2.3.10-bin --with-memcached=$build/memcached-1.4.7-bin --with-tinycdb=$build/tinycdb-bin --with-leveldb=$build/leveldb --with-js-include=$build/js-1.8.5-bin/include/js --with-js-lib=$build/js-1.8.5-bin/lib --enable-pagespeed --with-pagespeed=$build/page-speed-1.9-bin --with-libcloud=$build/libcloud-0.4.2-bin --enable-threads --enable-python --enable-opencl --with-libxml2=$build/libxml2-2.7.7-bin --enable-chat --with-libstrophe=$build/libstrophe-bin --enable-openid --with-mod-auth-openid=$build/mod-auth-openid-bin --enable-oauth --with-liboauth=$build/liboauth-0.9.1-bin --enable-mod-security --with-mod-security=$build/modsecurity-apache-2.6.1-bin
 make
 make install
 if [ "$?" != "0" ]; then
@@ -305,8 +315,8 @@
 cd $build
 
 # Create src archive
-tar czf tuscany-sca-cpp-1.0-src.tar.gz apache-libcloud-incubating-0.4.2 apache-libcloud-incubating-0.4.2.tar.bz2 apr-1.4.x apr-1.4.x-bin autoconf-2.13 autoconf-2.13-bin autoconf-2.13.tar.gz curl-7.19.5 curl-7.19.5-bin curl-7.19.5.tar.gz expat-2.0.1 expat-2.0.1-bin expat-2.0.1.tar.gz htmltidy-bin httpd-2.3.10 httpd-2.3.10-alpha.tar.gz httpd-2.3.10-bin js-1.8.5-bin js-1.8.5 js185-1.0.0.tar.gz libcloud-0.4.2-bin libevent-2.0.13-stable libevent-2.0.13-stable-bin libevent-2.0.13-stable.tar.gz liboauth-0.9.1 liboauth-0.9.1-bin liboauth-0.9.1.tar.gz libopkele libopkele-bin libstrophe libstrophe-bin libxml2-2.7.7 libxml2-2.7.7-bin libxml2-sources-2.7.7.tar.gz memcached-1.4.7 memcached-1.4.7-bin memcached-1.4.7.tar.gz mod_auth_openid mod-auth-openid-bin modsecurity-apache_2.6.1 modsecurity-apache-2.6.0-bin modsecurity-apache_2.6.0.tar.gz modsecurity-crs_2.2.1 modsecurity-crs_2.2.1.tar.gz nspr-4.8.8-bin nspr-4.8.8 nspr-4.8.8.tar.gz nuvem pcre-8.12 pcre-8.12-bin pcre-8.12.zip pkg-config-0.25 pkg-config-0.25-bin pkg-config-0.25.tar.gz tidy tinycdb tinycdb-bin leveldb tuscany-sca-cpp tuscany-sca-cpp-bin
+tar czf tuscany-sca-cpp-1.0-src.tar.gz apache-libcloud-incubating-0.4.2 apache-libcloud-incubating-0.4.2.tar.bz2 apr-1.4.x apr-1.4.x-bin autoconf-2.13 autoconf-2.13-bin autoconf-2.13.tar.gz curl-7.19.5 curl-7.19.5-bin curl-7.19.5.tar.gz expat-2.0.1 expat-2.0.1-bin expat-2.0.1.tar.gz htmltidy-bin httpd-2.3.10 httpd-2.3.10-alpha.tar.gz httpd-2.3.10-bin js-1.8.5-bin js-1.8.5 js185-1.0.0.tar.gz libcloud-0.4.2-bin libevent-2.0.13-stable libevent-2.0.13-stable-bin libevent-2.0.13-stable.tar.gz liboauth-0.9.1 liboauth-0.9.1-bin liboauth-0.9.1.tar.gz libopkele libopkele-bin libstrophe libstrophe-bin libxml2-2.7.7 libxml2-2.7.7-bin libxml2-sources-2.7.7.tar.gz memcached-1.4.7 memcached-1.4.7-bin memcached-1.4.7.tar.gz mod_auth_openid mod-auth-openid-bin modsecurity-apache_2.6.1 modsecurity-apache-2.6.0-bin modsecurity-apache_2.6.0.tar.gz modsecurity-crs_2.2.1 modsecurity-crs_2.2.1.tar.gz nspr-4.8.8-bin nspr-4.8.8 nspr-4.8.8.tar.gz nuvem page-speed-1.9 page-speed-1.9-bin page-speed-sdk.zip pcre-8.12 pcre-8.12-bin pcre-8.12.zip pkg-config-0.25 pkg-config-0.25-bin pkg-config-0.25.tar.gz tidy tinycdb tinycdb-bin leveldb tuscany-sca-cpp tuscany-sca-cpp-bin
 
 # Create bin archive
-tar czf tuscany-sca-cpp-1.0.tar.gz apr-1.4.x-bin curl-7.19.5-bin expat-2.0.1-bin htmltidy-bin httpd-2.3.10-bin js-1.8.5-bin libcloud-0.4.2-bin libevent-2.0.13-stable-bin liboauth-0.9.1-bin libopkele-bin libstrophe-bin libxml2-2.7.7-bin memcached-1.4.7-bin mod-auth-openid-bin modsecurity-apache-2.6.1-bin nspr-4.8.8-bin nuvem/nuvem-parallel pcre-8.12-bin tinycdb-bin leveldb tuscany-sca-cpp tuscany-sca-cpp-bin
+tar czf tuscany-sca-cpp-1.0.tar.gz apr-1.4.x-bin curl-7.19.5-bin expat-2.0.1-bin htmltidy-bin httpd-2.3.10-bin js-1.8.5-bin libcloud-0.4.2-bin libevent-2.0.13-stable-bin liboauth-0.9.1-bin libopkele-bin libstrophe-bin libxml2-2.7.7-bin memcached-1.4.7-bin mod-auth-openid-bin modsecurity-apache-2.6.1-bin nspr-4.8.8-bin nuvem/nuvem-parallel page-speed-1.9-bin pcre-8.12-bin tinycdb-bin leveldb tuscany-sca-cpp tuscany-sca-cpp-bin
 
diff --git a/modules/edit/Makefile.am b/modules/edit/Makefile.am
index 55eca3e..241d06d 100644
--- a/modules/edit/Makefile.am
+++ b/modules/edit/Makefile.am
@@ -21,6 +21,20 @@
 dist_mod_SCRIPTS = start stop ssl-start mkapplinks
 
 nobase_dist_mod_DATA = edit.composite *.py htdocs/*.html htdocs/*.js htdocs/*.cmf htdocs/*.ico htdocs/home/*.png htdocs/home/*.b64 htdocs/*.txt htdocs/account/*.html htdocs/create/*.html htdocs/clone/*.html htdocs/app/*.html htdocs/store/*.html htdocs/stats/*.html htdocs/graph/*.html htdocs/home/*.html htdocs/page/*.html htdocs/login/*.html htdocs/logout/*.html htdocs/notauth/*.html htdocs/notfound/*.html htdocs/oops/*.html htdocs/public/*.html htdocs/public/*.png htdocs/public/*.b64 palettes/*/palette.composite apps/*/app.composite apps/*/app.stats apps/*/htdocs/app.html dashboards/*/user.apps store/*/store.apps
+
 EXTRA_DIST = edit.composite *.py htdocs/*.html htdocs/*.js htdocs/*.cmf htdocs/*.ico htdocs/home/*.png htdocs/home/*.b64 htdocs/*.txt htdocs/account/*.html htdocs/create/*.html htdocs/clone/*.html htdocs/app/*.html htdocs/store/*.html htdocs/stats/*.html htdocs/graph/*.html htdocs/home/*.html htdocs/page/*.html htdocs/login/*.html htdocs/logout/*.html htdocs/notauth/*.html htdocs/notfound/*.html htdocs/oops/*.html htdocs/public/*.html htdocs/public/*.png htdocs/public/*.b64 palettes/*/palette.composite apps/*/app.composite apps/*/app.stats apps/*/htdocs/app.html dashboards/*/user.apps store/*/store.apps
 
+BUILT_SOURCES = minify_html.stamp minify_js.stamp
+minify_html.stamp: htdocs/*.html htdocs/*/*.html
+	find htdocs -name "*-min.html" -exec rm {} \;
+	find htdocs -name "*.html" -exec ../http/minify-html {} \;
+	touch minify_html.stamp
+
+minify_js.stamp: htdocs/*.js
+	find htdocs -name "*-min.js" -exec rm {} \;
+	find htdocs -name "*.js" -exec ../http/minify-js {} \;
+	touch minify_js.stamp
+
+CLEANFILES = *.stamp
+
 endif
diff --git a/modules/edit/htdocs/app/cache-manifest.cmf b/modules/edit/htdocs/app/cache-manifest.cmf
index 4f3358e..0be3e66 100644
--- a/modules/edit/htdocs/app/cache-manifest.cmf
+++ b/modules/edit/htdocs/app/cache-manifest.cmf
@@ -9,7 +9,7 @@
 /notfound/
 /notyet/
 /oops/
-/public/iframe.html
+/public/iframe-min.html
 /public/img.png
 /public/touchicon.png
 
diff --git a/modules/edit/htdocs/app/index.html b/modules/edit/htdocs/app/index.html
index cb89cd0..9309c7c 100644
--- a/modules/edit/htdocs/app/index.html
+++ b/modules/edit/htdocs/app/index.html
@@ -77,7 +77,7 @@
 <div id="headdiv" class="hsection">
 <script type="text/javascript">
 (function() {
-$('headdiv').appendChild(ui.declareScript(appcache.get('/headconfig.js')));
+$('headdiv').appendChild(ui.declareScript(appcache.get('/headconfig-min.js')));
 })();
 </script>
 </div>
@@ -96,8 +96,9 @@
 var contentdiv = $('content');
 
 /**
- * Start, stop, timer, animation and location components.
+ * Initialize the app HTTP clients.
  */
+var pagecomp = sca.httpclient('page', '');
 var startcomp = sca.httpclient('start', '/start');
 var stopcomp = sca.httpclient('stop', '/stop');
 var timercomp = sca.httpclient('timer', '/timer');
@@ -109,10 +110,9 @@
  */
 var appresources = [
     ['/all-min.js'],
-    ['/app.html'],
     ['/ui-min.css'],
-    ['/footconfig.js'],
-    ['/headconfig.js'],
+    ['/footconfig-min.js'],
+    ['/headconfig-min.js'],
 ];
 
 /**
@@ -266,12 +266,12 @@
 
                 // Define the stylesheet
                 if (s != '') {
-                    var esheet = contentdiv.getElementById('style_' + e.id);
+                    var esheet = ui.elementByID(contentdiv, 'style_' + e.id);
                     if (isNil(esheet)) {
                         var nesheet = document.createElement('style');
                         nesheet.id = 'style_' + e.id;
                         nesheet.type = 'text/css';
-                        contentdiv.getElementsByTagName('head')[0].appendChild(nesheet);
+                        document.head.appendChild(nesheet);
                         nesheet.innerHTML = s;
                     } else {
                         esheet.innerHTML = s;
@@ -526,18 +526,6 @@
 }
 
 /**
- * Get document from a component.
- */
-function getdoc(comp, name, uri) {
-    try {
-        return comp.getnocache(uri);
-    } catch(e) {
-        log('exception on get(' + name + ', ' + uri + ')', e);
-        return null;
-    }
-}
-
-/**
  * Get app data from the main app page component.
  */
 function getpagedata() {
@@ -567,19 +555,48 @@
             bindwidgethandler(e);
         }
 
-        // Get the component app data
-        var doc = getdoc(startcomp, 'start', location.search);
-
         // Setup the widgets
         map(setupwidget, filter(function(e) { return !isNil(e.id); }, nodeList(ui.elementByID(contentdiv, 'page').childNodes)));
 
-        // Display data on the page
-        displaypage(doc);
+        // Get the component app data
+        startcomp.get(location.search, function(doc, e) {
+            if (isNil(doc)) {
+                log('exception on get(start, ' + location.search + ')', e);
+                return false;
+            }
+
+            // Display data on the page
+            displaypage(doc);
+        });
 
         // Get and eval the optional timer, animation and location watch setup scripts
-        evalcompinit(getdoc(timercomp, 'timer', 'setup'));
-        evalcompinit(getdoc(animationcomp, 'animation', 'setup'));
-        evalcompinit(getdoc(locationcomp, 'location', 'setup'));
+        timercomp.get('setup', function(doc, e) {
+            if (isNil(doc)) {
+                log('exception on get(timer, setup)', e);
+                return false;
+            }
+
+            // Evaluate the component init expression
+            return evalcompinit(doc);
+        });
+        animationcomp.get('setup', function(doc, e) {
+            if (isNil(doc)) {
+                log('exception on get(animation, setup)', e);
+                return false;
+            }
+
+            // Evaluate the component init expression
+            return evalcompinit(doc);
+        });
+        locationcomp.get('setup', function(doc, e) {
+            if (isNil(doc)) {
+                log('exception on get(location, setup)', e);
+                return false;
+            }
+
+            // Evaluate the component init expression
+            return evalcompinit(doc);
+        });
 
         return true;
 
@@ -619,7 +636,16 @@
  */
 function buttonClickHandler(id) {
     try {
-        return updatepage(docdata(getdoc(sca.component(id), 'button', compquery())));
+        var uri = compquery();
+        return sca.component(id).get(uri, function(doc, e) {
+            if (isNil(doc)) {
+                log('exception on get(button, ' + uri + ')', e);
+                return false;
+            }
+
+            // Inject data into the page
+            updatepage(docdata(doc));
+        });
     } catch(e) {
         log('exception in buttonClickHandler()', e);
         return true;
@@ -631,7 +657,16 @@
  */
 function intervalHandler() {
     try {
-        return updatepage(docdata(getdoc(timercomp, 'timer', compquery())));
+        var uri = compquery();
+        return timercomp.get(uri, function(doc, e) {
+            if (isNil(doc)) {
+                log('exception on get(timer, ' + uri + ')', e);
+                return false;
+            }
+
+            // Inject data into the page
+            updatepage(docdata(doc));
+        });
     } catch(e) {
         log('exception in intervalHandler()', e);
         return true;
@@ -655,50 +690,64 @@
  * Handle an animation event.
  */
 var animationData = null;
+var gettingAnimationData = false;
 var currentAnimationData = null;
 var animationLoop = 0;
 var currentAnimationLoop = 0;
 
 function animationHandler() {
     try {
-        // Get animation data if necessary
-        if (isNil(animationData)) {
-            animationData = docdata(getdoc(animationcomp, 'animation', compquery()));
-            if (isNil(animationData)) {
-                // Retry later
-                return true;
-            }
-            currentAnimationData = animationData;
-            currentAnimationLoop = animationLoop;
-        }
+        function applyAnimation() {
+            // Update page with current animation data
+            updatepage(car(currentAnimationData));
 
-        // Update page with animation data
-        updatepage(car(currentAnimationData));
+            // End of animation?
+            if (isNil(cdr(currentAnimationData))) {
+                if (currentAnimationLoop == -1) {
+                    // Repeat current animation forever
+                    currentAnimationData = animationData;
+                    return true;
+                }
 
-        // End of animation?
-        if (isNil(cdr(currentAnimationData))) {
-            if (currentAnimationLoop == -1) {
-                // Repeat current animation forever
+                currentAnimationLoop = currentAnimationLoop - 1;
+                if (currentAnimationLoop <= 0) {
+                    // Get next animation data
+                    currentAnimationData = null;
+                    animationData = null;
+                    return true;
+                }
+
+                // Repeat animation
                 currentAnimationData = animationData;
                 return true;
             }
 
-            currentAnimationLoop = currentAnimationLoop - 1;
-            if (currentAnimationLoop <= 0) {
-                // Get next animation data
-                currentAnimationData = null;
-                animationData = null;
-                return true;
-            }
-
-            // Repeat animation
-            currentAnimationData = animationData;
+            // Move to the next animation frame
+            currentAnimationData = cdr(currentAnimationData);
             return true;
         }
 
-        // Move to the next animation frame
-        currentAnimationData = cdr(currentAnimationData);
-        return true;
+        // Get new animation data if necessary
+        if (isNil(animationData)) {
+            if (gettingAnimationData)
+                return true;
+            var uri = compquery();
+            return animationcomp.get(uri, function(doc, e) {
+                if (isNil(doc)) {
+                    log('exception on get(animation, ' + uri + ')', e);
+                    return false;
+                }
+
+                // Apply the new animation
+                currentAnimationData = docdata(doc);
+                currentAnimationLoop = animationLoop;
+                gettingAnimationData = false;
+                applyAnimation();
+            });
+        }
+
+        // Apply the current animation
+        return applyAnimation();
 
     } catch(e) {
         log('exception in animationHandler()', e);
@@ -729,9 +778,18 @@
 function locationHandler(pos) {
     try {
         geoposition = pos;
-        return updatepage(docdata(getdoc(locationcomp, 'location', compquery())));
+        var uri = compquery();
+        return locationcomp.get(uri, function(doc, e) {
+            if (isNil(doc)) {
+                log('exception on get(location, ' + uri + ')', e);
+                return false;
+            }
+
+            // Inject data into the page
+            updatepage(docdata(doc));
+        });
     } catch(e) {
-        locationErrorHandler(e);
+        return locationErrorHandler(e);
     }
 }
 
@@ -758,6 +816,7 @@
         } catch(e) {
             log('exception in installLocationHandler()', e);
         }
+        return true;
     }
 
     installLocationHandler();
@@ -766,11 +825,19 @@
 }
 
 // Load the app page
-var appcontent = appcache.get('/app.html');
-contentdiv.innerHTML = appcontent;
+pagecomp.get('app.html', function(doc, e) {
+    log('page get');
+    if (isNil(doc)) {
+        log('exception getting app page', e);
+        return false;
+    }
 
-// Merge in the app data
-getpagedata();
+    // Set the app HTML page into the content div
+    contentdiv.innerHTML = doc;
+
+    // Merge in the app data
+    getpagedata();
+});
 
 /**
  * Document load post processing.
@@ -791,7 +858,7 @@
 <div id="footdiv" class="fsection">
 <script type="text/javascript">
 (function() {
-$('footdiv').appendChild(ui.declareScript(appcache.get('/footconfig.js')));
+$('footdiv').appendChild(ui.declareScript(appcache.get('/footconfig-min.js')));
 })();
 </script>
 </div>
diff --git a/modules/edit/htdocs/cache-manifest.cmf b/modules/edit/htdocs/cache-manifest.cmf
index 4f3358e..0be3e66 100644
--- a/modules/edit/htdocs/cache-manifest.cmf
+++ b/modules/edit/htdocs/cache-manifest.cmf
@@ -9,7 +9,7 @@
 /notfound/
 /notyet/
 /oops/
-/public/iframe.html
+/public/iframe-min.html
 /public/img.png
 /public/touchicon.png
 
diff --git a/modules/edit/htdocs/graph/index.html b/modules/edit/htdocs/graph/index.html
index 730506c..3cc7359 100644
--- a/modules/edit/htdocs/graph/index.html
+++ b/modules/edit/htdocs/graph/index.html
@@ -2092,7 +2092,7 @@
 
     // Get the component result data
     var comp = sca.component(gcomp.id, appname);
-    comp.getnocache('', function(doc) {
+    comp.get('', function(doc) {
         function displaydata(t, w) {
             pdiv.style.width = w;
             pdiv.innerHTML = t;
diff --git a/modules/edit/htdocs/index.html b/modules/edit/htdocs/index.html
index bba70ba..869ae30 100644
--- a/modules/edit/htdocs/index.html
+++ b/modules/edit/htdocs/index.html
@@ -77,7 +77,7 @@
 <div id="headdiv" class="hsection">
 <script type="text/javascript">
 (function() {
-$('headdiv').appendChild(ui.declareScript(appcache.get('/headconfig.js')));
+$('headdiv').appendChild(ui.declareScript(appcache.get('/headconfig-min.js')));
 })();
 </script>
 </div>
@@ -117,15 +117,15 @@
     ['/account/', 'flip'],
     ['/clone/', 'flip'],
     ['/create/', 'flip'],
-    ['/footconfig.js'],
+    ['/footconfig-min.js'],
     ['/graph/', 'flip'],
-    ['/headconfig.js'],
+    ['/headconfig-min.js'],
     ['/home/', 'right'],
     ['/home/home.b64'],
     ['/page/', 'flip'],
     ['/public/app.b64'],
     ['/public/grid72.b64'],
-    ['/public/iframe.html'],
+    ['/public/iframe-min.html'],
     ['/public/img.b64'],
     ['/public/user.b64'],
     ['/stats/', 'flip'],
@@ -427,7 +427,7 @@
 <div id="footdiv" class="fsection">
 <script type="text/javascript">
 (function() {
-$('footdiv').appendChild(ui.declareScript(appcache.get('/footconfig.js')));
+$('footdiv').appendChild(ui.declareScript(appcache.get('/footconfig-min.js')));
 })();
 </script>
 </div>
diff --git a/modules/edit/htdocs/notauth/index.html b/modules/edit/htdocs/notauth/index.html
index 4b6eb7e..4827238 100644
--- a/modules/edit/htdocs/notauth/index.html
+++ b/modules/edit/htdocs/notauth/index.html
@@ -76,7 +76,7 @@
 <div id="headdiv" class="hsection">
 <script type="text/javascript">
 (function() {
-$('headdiv').appendChild(ui.declareScript(appcache.get('/headconfig.js')));
+$('headdiv').appendChild(ui.declareScript(appcache.get('/headconfig-min.js')));
 })();
 </script>
 </div>
@@ -133,7 +133,7 @@
 <div id="footdiv" class="fsection">
 <script type="text/javascript">
 (function() {
-$('footdiv').appendChild(ui.declareScript(appcache.get('/footconfig.js')));
+$('footdiv').appendChild(ui.declareScript(appcache.get('/footconfig-min.js')));
 })();
 </script>
 </div>
diff --git a/modules/edit/htdocs/notfound/index.html b/modules/edit/htdocs/notfound/index.html
index 4d11a1a..743ae59 100644
--- a/modules/edit/htdocs/notfound/index.html
+++ b/modules/edit/htdocs/notfound/index.html
@@ -76,7 +76,7 @@
 <div id="headdiv" class="hsection">
 <script type="text/javascript">
 (function() {
-$('headdiv').appendChild(ui.declareScript(appcache.get('/headconfig.js')));
+$('headdiv').appendChild(ui.declareScript(appcache.get('/headconfig-min.js')));
 })();
 </script>
 </div>
@@ -134,7 +134,7 @@
 <div id="footdiv" class="fsection">
 <script type="text/javascript">
 (function() {
-$('footdiv').appendChild(ui.declareScript(appcache.get('/footconfig.js')));
+$('footdiv').appendChild(ui.declareScript(appcache.get('/footconfig-min.js')));
 })();
 </script>
 </div>
diff --git a/modules/edit/htdocs/notyet/index.html b/modules/edit/htdocs/notyet/index.html
index 2f9f775..fba173f 100644
--- a/modules/edit/htdocs/notyet/index.html
+++ b/modules/edit/htdocs/notyet/index.html
@@ -76,7 +76,7 @@
 <div id="headdiv" class="hsection">
 <script type="text/javascript">
 (function() {
-$('headdiv').appendChild(ui.declareScript(appcache.get('/headconfig.js')));
+$('headdiv').appendChild(ui.declareScript(appcache.get('/headconfig-min.js')));
 })();
 </script>
 </div>
@@ -134,7 +134,7 @@
 <div id="footdiv" class="fsection">
 <script type="text/javascript">
 (function() {
-$('footdiv').appendChild(ui.declareScript(appcache.get('/footconfig.js')));
+$('footdiv').appendChild(ui.declareScript(appcache.get('/footconfig-min.js')));
 })();
 </script>
 </div>
diff --git a/modules/edit/htdocs/oops/index.html b/modules/edit/htdocs/oops/index.html
index 70fe399..1e9ea06 100644
--- a/modules/edit/htdocs/oops/index.html
+++ b/modules/edit/htdocs/oops/index.html
@@ -76,7 +76,7 @@
 <div id="headdiv" class="hsection">
 <script type="text/javascript">
 (function() {
-$('headdiv').appendChild(ui.declareScript(appcache.get('/headconfig.js')));
+$('headdiv').appendChild(ui.declareScript(appcache.get('/headconfig-min.js')));
 })();
 </script>
 </div>
@@ -133,7 +133,7 @@
 <div id="footdiv" class="fsection">
 <script type="text/javascript">
 (function() {
-$('footdiv').appendChild(ui.declareScript(appcache.get('/footconfig.js')));
+$('footdiv').appendChild(ui.declareScript(appcache.get('/footconfig-min.js')));
 })();
 </script>
 </div>
diff --git a/modules/edit/htdocs/page/index.html b/modules/edit/htdocs/page/index.html
index dd33f34..1b4c455 100644
--- a/modules/edit/htdocs/page/index.html
+++ b/modules/edit/htdocs/page/index.html
@@ -75,7 +75,7 @@
 </span>
 <span class="link" id="palette:link" style="position: absolute; left: 0px; top: 340px;"><a href="/"><span>link</span></a></span>
 <span class="text" id="palette:text" style="position: absolute; left: 0px; top: 370px;"><span>text</span></span>
-<span class="iframe fakeframe" id="palette:iframe" style="position: absolute; left: 0px; top: 400px; width: 200px;"><a href="/public/iframe.html"><span class="fakeframe"><span>frame ...</span></span></a></span>
+<span class="iframe fakeframe" id="palette:iframe" style="position: absolute; left: 0px; top: 400px; width: 200px;"><a href="/public/iframe-min.html"><span class="fakeframe"><span>frame ...</span></span></a></span>
 <span class="img" id="palette:img" style="position: absolute; left: 0px; top: 430px;"><img id="imgimg"/></span>
 </div>
 
@@ -555,7 +555,7 @@
         return t;
     }
     if (e.className == 'iframe') {
-        car(childElements(e)).href = isNil(c)? '/public/iframe.html' : car(c);
+        car(childElements(e)).href = isNil(c)? '/public/iframe-min.html' : car(c);
         return t;
     }
     return '';
diff --git a/modules/http/Makefile.am b/modules/http/Makefile.am
index 07a7979..89b285e 100644
--- a/modules/http/Makefile.am
+++ b/modules/http/Makefile.am
@@ -20,7 +20,7 @@
 incl_HEADERS = *.hpp
 incldir = $(prefix)/include/modules/http
 
-dist_mod_SCRIPTS = httpd-conf httpd-addr httpd-start httpd-stop httpd-restart ssl-ca-conf ssl-cert-conf ssl-cert-find httpd-ssl-conf basic-auth-conf cert-auth-conf form-auth-conf open-auth-conf passwd-auth-conf group-auth-conf proxy-conf proxy-ssl-conf proxy-member-conf proxy-ssl-member-conf vhost-conf vhost-ssl-conf tunnel-ssl-conf httpd-worker-conf httpd-event-conf
+dist_mod_SCRIPTS = httpd-conf httpd-addr httpd-start httpd-stop httpd-restart ssl-ca-conf ssl-cert-conf ssl-cert-find httpd-ssl-conf basic-auth-conf cert-auth-conf form-auth-conf open-auth-conf passwd-auth-conf group-auth-conf proxy-conf proxy-ssl-conf proxy-member-conf proxy-ssl-member-conf vhost-conf vhost-ssl-conf tunnel-ssl-conf httpd-worker-conf httpd-event-conf minify-html minify-js minify-css
 moddir = $(prefix)/modules/http
 
 curl_test_SOURCES = curl-test.cpp
@@ -45,7 +45,7 @@
 libmod_tuscany_openauth${libsuffix}:
 	ln -s .libs/libmod_tuscany_openauth${libsuffix}
 
-mod_DATA = httpd.prefix httpd-apachectl.prefix httpd-modules.prefix curl.prefix
+mod_DATA = httpd.prefix httpd-apachectl.prefix httpd-modules.prefix curl.prefix pagespeed.prefix
 nobase_dist_mod_DATA = conf/*
 
 EXTRA_DIST = htdocs/index.html htdocs/login/index.html htdocs/logout/index.html
@@ -59,6 +59,18 @@
 curl.prefix: $(top_builddir)/config.status
 	echo ${CURL_PREFIX} >curl.prefix
 
+if WANT_PAGESPEED
+
+pagespeed.prefix: $(top_builddir)/config.status
+	echo ${PAGESPEED_PREFIX} >pagespeed.prefix
+
+else
+
+pagespeed.prefix: $(top_builddir)/config.status
+	echo "" >pagespeed.prefix
+
+endif
+
 if WANT_MODSECURITY
 
 modsecurity.prefix: $(top_builddir)/config.status
diff --git a/modules/http/httpd-conf b/modules/http/httpd-conf
index d672b2d..6c80e1a 100755
--- a/modules/http/httpd-conf
+++ b/modules/http/httpd-conf
@@ -98,7 +98,7 @@
 
 # Set default document root
 DocumentRoot $htdocs
-DirectoryIndex index.html
+DirectoryIndex index-min.html index.html
 
 # Protect server files
 <Directory />
diff --git a/modules/http/minify-css b/modules/http/minify-css
new file mode 100755
index 0000000..e337f17
--- /dev/null
+++ b/modules/http/minify-css
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+#    
+#  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.
+
+# Minify a CSS file
+here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
+pagespeed_prefix=`cat $here/pagespeed.prefix`
+
+if [ "${pagespeed_prefix}" = "" ]; then
+    minify_css="cat"
+else
+    minify_css="${pagespeed_prefix}/jsmin_bin"
+fi
+
+css="$1"
+mincss="${css%.*}-min.css"
+
+${minify_css} <${css} >${mincss}
+
diff --git a/modules/http/minify-html b/modules/http/minify-html
new file mode 100755
index 0000000..a1946d1
--- /dev/null
+++ b/modules/http/minify-html
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+#    
+#  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.
+
+# Minify an HTML file
+here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
+pagespeed_prefix=`cat $here/pagespeed.prefix`
+
+if [ "${pagespeed_prefix}" = "" ]; then
+    minify_html="cp"
+else
+    minify_html="${pagespeed_prefix}/minify_html_bin"
+fi
+
+html="$1"
+minhtml="${html%.*}-min.html"
+
+${minify_html} ${html} ${minhtml}
+
diff --git a/modules/http/minify-js b/modules/http/minify-js
new file mode 100755
index 0000000..41fbe82
--- /dev/null
+++ b/modules/http/minify-js
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+#    
+#  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.
+
+# Minify a JS file
+here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
+pagespeed_prefix=`cat $here/pagespeed.prefix`
+
+if [ "${pagespeed_prefix}" = "" ]; then
+    minify_js="cat"
+else
+    minify_js="${pagespeed_prefix}/jsmin_bin"
+fi
+
+js="$1"
+minjs="${js%.*}-min.js"
+
+${minify_js} <${js} >${minjs}
+
diff --git a/modules/js/Makefile.am b/modules/js/Makefile.am
index b2933e8..1ef3fbd 100644
--- a/modules/js/Makefile.am
+++ b/modules/js/Makefile.am
@@ -18,11 +18,17 @@
 incl_HEADERS = *.hpp
 incldir = $(prefix)/include/modules/js
 
-BUILT_SOURCES = htdocs/all.js
+BUILT_SOURCES = htdocs/all.js htdocs/all-min.js htdocs/ui-min.css
 htdocs/all.js: htdocs/util.js htdocs/elemutil.js htdocs/xmlutil.js htdocs/atomutil.js htdocs/jsonutil.js htdocs/scdl.js htdocs/ui.js htdocs/component.js
 	cat htdocs/util.js htdocs/elemutil.js htdocs/xmlutil.js htdocs/atomutil.js htdocs/jsonutil.js htdocs/scdl.js htdocs/ui.js htdocs/component.js >htdocs/all.js
 
-CLEANFILES = htdocs/all.js
+htdocs/all-min.js: htdocs/all.js
+	../http/minify-js htdocs/all.js
+
+htdocs/ui-min.css: htdocs/ui.css
+	../http/minify-css htdocs/ui.css
+
+CLEANFILES = htdocs/all.js htdocs/all-min.js
 
 moddir = $(prefix)/modules/js
 nobase_dist_mod_DATA = htdocs/*.js htdocs/*.css
diff --git a/modules/js/htdocs/all-min.js b/modules/js/htdocs/all-min.js
deleted file mode 100644
index b214be0..0000000
--- a/modules/js/htdocs/all-min.js
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
- * 
- * 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.    
- */
-function cons(car,cdr){var a=new Array();a.push(car);return a.concat(cdr);}
-function car(l){return l[0];}
-function first(l){return l[0];}
-function cdr(l){return l.slice(1);}
-function rest(l){return l.slice(1);}
-function cadr(l){return l[1];}
-function cddr(l){return l.slice(2);}
-function caddr(l){return l[2];}
-function cdddr(l){return l.slice(3);}
-function cadddr(l){return l[3];}
-function append(a,b){return a.concat(b);}
-function reverse(l){return l.slice(0).reverse();}
-function range(a,b){var l=new Array();for(var x=a;x<b;x++)
-l.push(x);return l;}
-function isNil(v){return(v==null||typeof v=='undefined'||(v.constructor==Array&&v.length==0));}
-function isSymbol(v){return(typeof v=='string'&&v.slice(0,1)=="'");}
-function isString(v){return(typeof v=='string'&&v.slice(0,1)!="'");}
-function isList(v){return(v!=null&&typeof v!='undefined'&&v.constructor==Array);}
-function isTaggedList(v,t){return(isList(v)&&!isNil(v)&&car(v)==t);}
-var emptylist=new Array();function mklist(){if(arguments.length==0)
-return emptylist;var a=new Array();for(i=0;i<arguments.length;i++)
-a[i]=arguments[i];return a;}
-function length(l){return l.length;}
-function assoc(k,l){if(isNil(l))
-return emptylist;var n=l.length;for(var i=0;i<n;i++){if(k==car(l[i]))
-return l[i];}
-return emptylist;}
-function map(f,l){if(isNil(l))
-return l;var n=l.length;var a=new Array();for(var i=0;i<n;i++){a.push(f(l[i]));}
-return a;}
-function filter(f,l){if(isNil(l))
-return l;var n=l.length;var a=new Array();for(var i=0;i<n;i++){if(f(l[i]))
-a.push(l[i]);}
-return a;}
-function reduce(f,i,l){if(isNil(l))
-return i;return reduce(f,f(i,car(l)),cdr(l));}
-function tokens(path){return filter(function(s){return length(s)!=0;},path.split("/"));}
-var rconsole;function log(v){try{var s='';for(i=0;i<arguments.length;i++){s=s+writeValue(arguments[i]);if(i<arguments.length)
-s=s+' ';}
-if(rconsole){try{rconsole.log(s);}catch(e){}}
-try{console.log(s);}catch(e){}}catch(e){}
-return true;}
-function debug(o){try{for(f in o){try{log('debug '+f+'='+o[f]);}catch(e){}}}catch(e){}
-return true;}
-function isIE(){if(typeof isIE.detected!='undefined')
-return isIE.detected;isIE.detected=navigator.appName=='Microsoft Internet Explorer';return isIE.detected;};var config;if(isNil(config))
-config={};function AssertException(){}
-AssertException.prototype.toString=function(){return'AssertException';};function assert(exp){if(!exp)
-throw new AssertException();}
-function writeStrings(l){if(isNil(l))
-return'';var s='';var n=l.length;for(var i=0;i<n;i++){s=s+l[i];}
-return s;}
-function writeValue(v){function writePrimitive(p){if(isSymbol(p))
-return''+p.substring(1);if(isString(p))
-return'"'+p+'"';return''+p;}
-function writeList(l){if(isNil(l))
-return'';return' '+writeValue(car(l))+writeList(cdr(l));}
-if(!isList(v))
-return writePrimitive(v);if(isNil(v))
-return'()';return'('+writeValue(car(v))+writeList(cdr(v))+')';}
-function memo(obj,key,f){if(!('memo'in obj)){obj.memo={};return obj.memo[key]=f();}
-if(key in obj.memo)
-return obj.memo[key];return obj.memo[key]=f();}
-function unmemo(obj){obj.memo={};return true;}
-function properties(o){var a=new Array();for(p in o)
-a.push(p);return a;}
-function domainname(host){var h=reverse(host.split('.'));return reverse(mklist(car(h),cadr(h))).join('.');}
-function issubdomain(host){return host.split('.').length>2;}
-function format(){var i=0;var s='';for(a in arguments){s=i==0?arguments[a]:s.replace('{'+a+'}',arguments[a]);i++;}
-return s;}
-function setcar(l,v){l[0]=v;return l;}
-function setcadr(l,v){l[1]=v;return l;}
-function setcaddr(l,v){l[2]=v;return l;}
-function setappend(a,b){if(isNil(b))
-return a;a.push(car(b));return setappend(a,cdr(b));}
-function setcdr(a,b){a.length=1;return setappend(a,b);}
-function setlist(a,b){if(b==a)
-return b;a.length=0;return setappend(a,b);}
-var element="'element"
-var attribute="'attribute"
-var atsign="'@"
-function isElement(v){return(!(!isList(v)||isNil(v)||car(v)!=element));}
-function isAttribute(v){return(!(!isList(v)||isNil(v)||car(v)!=attribute));}
-attributeName=cadr;attributeValue=caddr;elementName=cadr;function elementHasChildren(l){return!isNil(cddr(l));}
-elementChildren=cddr;function elementHasValue(l){var r=reverse(l);if(isSymbol(car(r)))
-return false;return(!(isList(car(r))&&!isNil(car(r))&&isSymbol(car(car(r)))))}
-function elementValue(l){return car(reverse(l));}
-function elementToValueIsList(v){if(!isList(v))
-return false;return isNil(v)||!isSymbol(car(v));}
-function elementToValue(t){if(isTaggedList(t,attribute))
-return mklist(atsign+attributeName(t).substring(1),attributeValue(t));if(isTaggedList(t,element)){if(elementHasValue(t)){if(!elementToValueIsList(elementValue(t)))
-return mklist(elementName(t),elementValue(t));return cons(elementName(t),mklist(elementsToValues(elementValue(t))));}
-return cons(elementName(t),elementsToValues(elementChildren(t)));}
-if(!isList(t))
-return t;return elementsToValues(t);}
-function elementToValueIsSymbol(v){return(!(!isList(v))||isNil(v)||!isSymbol(car(v)));}
-function elementToValueGroupValues(v,l){if(isNil(l)||!elementToValueIsSymbol(v)||!elementToValueIsSymbol(car(l)))
-return cons(v,l);if(car(car(l))!=car(v))
-return cons(v,l);if(!elementToValueIsList(cadr(car(l)))){var g=mklist(car(v),mklist(cdr(v),cdr(car(l))));return elementToValueGroupValues(g,cdr(l));}
-var g=mklist(car(v),cons(cdr(v),cadr(car(l))));return elementToValueGroupValues(g,cdr(l));}
-function elementsToValues(e){if(isNil(e))
-return e;return elementToValueGroupValues(elementToValue(car(e)),elementsToValues(cdr(e)));}
-function valueToElement(t){if(isList(t)&&!isNil(t)&&isSymbol(car(t))){var n=car(t);var v=isNil(cdr(t))?mklist():cadr(t);if(!isList(v)){if(n.substring(0,2)==atsign)
-return mklist(attribute,"'"+n.substring(2),v);return mklist(element,n,v);}
-if(isNil(v)||!isSymbol(car(v)))
-return cons(element,cons(n,mklist(valuesToElements(v))));return cons(element,cons(n,valuesToElements(cdr(t))));}
-if(!isList(t))
-return t;return valuesToElements(t);}
-function valuesToElements(l){if(isNil(l))
-return l;return cons(valueToElement(car(l)),valuesToElements(cdr(l)));}
-function selector(s){function evalSelect(s,v){if(isNil(s))
-return true;if(isNil(v))
-return false;if(car(s)!=car(v))
-return false;return evalSelect(cdr(s),cdr(v));}
-return function(v){return evalSelect(s,v);};}
-function namedAttribute(name,l){return memo(l,name,function(){var f=filter(function(v){return isAttribute(v)&&attributeName(v)==name;},l);if(isNil(f))
-return null;return car(f);});}
-function namedAttributeValue(name,l){var a=namedAttribute(name,l);if(a==null)
-return null
-return attributeValue(a);}
-function namedElementChildren(name,l){return memo(l,name,function(){return filter(function(v){return isElement(v)&&elementName(v)==name;},l);});}
-function namedElementChild(name,l){var f=namedElementChildren(name,l);if(isNil(f))
-return null;return car(f);}
-function setElement(l,e){setlist(l,e);l.memo={};}
-function nodeList(n){var l=new Array();if(isNil(n))
-return l;for(var i=0;i<n.length;i++)
-l[i]=n[i];return l;}
-function appendNodes(nodes,p){if(isNil(nodes))
-return p;p.appendChild(car(nodes));return appendNodes(cdr(nodes),p);};function childAttributes(e){return filter(function(n){return n.nodeType==2;},nodeList(e.attributes));}
-function childElements(e){return filter(function(n){return n.nodeType==1;},nodeList(e.childNodes));}
-function childText(e){function trim(s){return s.replace(/^\s*/,'').replace(/\s*$/,'');}
-return filter(function(n){return n.nodeType==3&&trim(n.nodeValue)!='';},nodeList(e.childNodes));}
-function readAttributes(p,a){if(isNil(a))
-return a;var x=car(a);return cons(mklist(attribute,"'"+x.nodeName,x.nodeValue),readAttributes(p,cdr(a)));}
-function readElement(e,childf){var l=append(append(mklist(element,"'"+e.nodeName),readAttributes(e,childf(e))),readElements(childElements(e),childf));var t=childText(e);if(isNil(t))
-return l;return append(l,mklist(car(t).nodeValue));}
-function readElements(l,childf){if(isNil(l))
-return l;return cons(readElement(car(l),childf),readElements(cdr(l),childf));}
-function isXML(l){if(isNil(l))
-return false;return car(l).substring(0,5)=='<?xml';}
-function parseXML(l){var s=writeStrings(l);var p=new DOMParser();return p.parseFromString(s,"text/xml");}
-function readXMLDocument(doc){var root=childElements(doc);if(isNil(root))
-return mklist();return mklist(readElement(car(root),childAttributes));}
-function readXHTMLElement(xhtml){function ieChildAttributes(e){var a=filter(function(n){if(n.nodeType!=2||isNil(n.nodeValue)||n.nodeValue=='')
-return false;if(n.nodeName=='contentEditable'||n.nodeName=='maxLength'||n.nodeName=='loop'||n.nodeName=='start')
-return false;return true;},nodeList(e.attributes));if(e.style.cssText=='')
-return a;var sa=new Object();sa.nodeName='style';sa.nodeValue=e.style.cssText;return cons(sa,a);}
-var childf=(typeof(XMLSerializer)!='undefined')?childAttributes:ieChildAttributes;return mklist(readElement(xhtml,childf));}
-function readXML(l){return readXMLDocument(parseXML(l));}
-function writeXMLDocument(doc){if(typeof(XMLSerializer)!='undefined')
-return mklist(new XMLSerializer().serializeToString(doc));return mklist(doc.xml);}
-function expandElementValues(n,l){if(isNil(l))
-return l;return cons(cons(element,cons(n,car(l))),expandElementValues(n,cdr(l)));}
-function writeList(l,node,doc){if(isNil(l))
-return node;var token=car(l);if(isTaggedList(token,attribute)){if(isIE()){var aname=attributeName(token).substring(1);if(aname!='xmlns')
-node.setAttribute(aname,''+attributeValue(token));}else
-node.setAttribute(attributeName(token).substring(1),''+attributeValue(token));}else if(isTaggedList(token,element)){function mkelem(tok,doc){function xmlns(l){if(isNil(l))
-return null;var t=car(l);if(isTaggedList(t,attribute)){if(attributeName(t).substring(1)=='xmlns')
-return attributeValue(t);}
-return xmlns(cdr(l));}
-var ns=xmlns(elementChildren(tok));if(isIE())
-return doc.createElementNS(ns!=null?ns:node.namespaceURI,elementName(tok).substring(1));if(ns==null)
-return doc.createElement(elementName(tok).substring(1));return doc.createElementNS(ns,elementName(tok).substring(1));}
-if(elementHasValue(token)){var v=elementValue(token);if(isList(v)){var e=expandElementValues(elementName(token),v);writeList(e,node,doc);}else{var child=mkelem(token,doc);writeList(elementChildren(token),child,doc);node.appendChild(child);}}else{var child=mkelem(token,doc);writeList(elementChildren(token),child,doc);node.appendChild(child);}}else
-node.appendChild(doc.createTextNode(''+token));writeList(cdr(l),node,doc);return node;}
-function mkXMLDocument(){return document.implementation.createDocument('','',null);}
-function writeXML(l,xmlTag){var doc=mkXMLDocument();writeList(l,doc,doc);if(!xmlTag)
-return writeXMLDocument(doc);return mklist('<?xml version="1.0" encoding="UTF-8"?>\n'+writeXMLDocument(doc)+'\n');}
-var atom={};atom.entryElementValues=function(e){var lt=filter(selector(mklist(element,"'title")),e);var t=isNil(lt)?'':elementValue(car(lt));var li=filter(selector(mklist(element,"'id")),e);var i=isNil(li)?'':elementValue(car(li));var lc=filter(selector(mklist(element,"'content")),e);return append(mklist(element,"'entry",mklist(element,"'title",t),mklist(element,"'id",i)),isNil(lc)?mklist():mklist(mklist(element,"'content",elementValue(car(lc)))))};atom.entriesElementValues=function(e){if(isNil(e))
-return e;return cons(atom.entryElementValues(car(e)),atom.entriesElementValues(cdr(e)));};atom.isATOMEntry=function(l){if(!isXML(l))
-return false;return car(l).match('<entry')!=null&&car(l).match('<feed')==null&&car(l).match('="http://www.w3.org/2005/Atom"')!=null;};atom.readATOMEntryDocument=function(doc){var e=readXMLDocument(doc);if(isNil(e))
-return mklist();return mklist(atom.entryElementValues(car(e)));};atom.readATOMEntry=function(l){return atom.readATOMEntryDocument(parseXML(l));};atom.isATOMFeed=function(l){if(!isXML(l))
-return false;return car(l).match('<feed')!=null&&car(l).match('="http://www.w3.org/2005/Atom"')!=null;};atom.readATOMFeedDocument=function(doc){var f=readXMLDocument(doc);if(isNil(f))
-return mklist();var t=filter(selector(mklist(element,"'title")),car(f));var i=filter(selector(mklist(element,"'id")),car(f));var e=filter(selector(mklist(element,"'entry")),car(f));return mklist(append(mklist(element,"'feed",mklist(element,"'title",elementValue(car(t))),mklist(element,"'id",elementValue(car(i)))),atom.entriesElementValues(e)));};atom.readATOMFeed=function(l){return atom.readATOMFeedDocument(parseXML(l));};atom.entryElement=function(l){var title=elementValue(namedElementChild("'title",l));var id=elementValue(namedElementChild("'id",l));var content=namedElementChild("'content",l);var text=isNil(content)?false:elementHasValue(content);return append(append(mklist(element,"'entry",mklist(attribute,"'xmlns","http://www.w3.org/2005/Atom"),mklist(element,"'title",mklist(attribute,"'type","text"),title),mklist(element,"'id",id)),isNil(content)?mklist():mklist(append(mklist(element,"'content",mklist(attribute,"'type",text?"text":"application/xml")),text?mklist(elementValue(content)):elementChildren(content)))),mklist(mklist(element,"'link",mklist(attribute,"'href",id))));};atom.entriesElements=function(l){if(isNil(l))
-return l;return cons(atom.entryElement(car(l)),atom.entriesElements(cdr(l)));};atom.writeATOMEntry=function(ll){var l=isNil(ll)?ll:car(ll);return writeXML(mklist(atom.entryElement(l)),true);};atom.writeATOMFeed=function(ll){var l=isNil(ll)?ll:car(ll);var lt=filter(selector(mklist(element,"'title")),l);var t=isNil(lt)?'':elementValue(car(lt));var li=filter(selector(mklist(element,"'id")),l);var i=isNil(li)?'':elementValue(car(li));var f=mklist(element,"'feed",mklist(attribute,"'xmlns","http://www.w3.org/2005/Atom"),mklist(element,"'title",mklist(attribute,"'type","text"),car(l)),mklist(element,"'id",cadr(l)));var le=filter(selector(mklist(element,"'entry")),l);if(isNil(le))
-return writeXML(mklist(f),true);if(!isNil(le)&&!isNil(car(le))&&isList(car(caddr(car(le))))){var fe=append(f,atom.entriesElements(caddr(car(le))));return writeXML(mklist(fe),true);}
-var fe=append(f,atom.entriesElements(le));return writeXML(mklist(fe),true);};var json={};json.Exception=function(code,message){this.name="JSONException";this.code=code;this.message=message;};json.Exception.prototype=new Error();json.Exception.prototype.toString=function(){return this.name+": "+this.message;};json.isJSArray=function(l){if(isNil(l))
-return true;var v=car(l);if(isSymbol(v))
-return false;if(isList(v))
-if(!isNil(v)&&isSymbol(car(v)))
-return false;return true;};json.jsPropertiesToValues=function(propertiesSoFar,o,i){if(isNil(i))
-return propertiesSoFar;var p=car(i);var jsv=o[p];var v=json.jsValToValue(jsv);if(typeof p=='string'){var n=''+p;if(n.slice(0,1)=='@')
-return json.jsPropertiesToValues(cons(mklist(attribute,"'"+n.slice(1),v),propertiesSoFar),o,cdr(i));if(isList(v)&&!json.isJSArray(v))
-return json.jsPropertiesToValues(cons(cons(element,cons("'"+n,v)),propertiesSoFar),o,cdr(i));return json.jsPropertiesToValues(cons(mklist(element,"'"+n,v),propertiesSoFar),o,cdr(i));}
-return json.jsPropertiesToValues(cons(v,propertiesSoFar),o,cdr(i));};json.jsValToValue=function(jsv){if(jsv==null)
-return null;if(isList(jsv))
-return json.jsPropertiesToValues(mklist(),jsv,reverse(range(0,jsv.length)));if(typeof jsv=='object')
-return json.jsPropertiesToValues(mklist(),jsv,reverse(properties(jsv)));if(typeof jsv=='string')
-return''+jsv;return jsv;}
-json.isJSON=function(l){if(isNil(l))
-return false;var s=car(l).slice(0,1);return s=="["||s=="{";};json.readJSON=function(l){var s=writeStrings(l);var obj;eval('obj = { \"val\": '+s+" }");return json.jsValToValue(obj.val);};json.valuesToJSElements=function(a,l,i){if(isNil(l))
-return a;var pv=json.valueToJSVal(car(l));a[i]=pv
-return json.valuesToJSElements(a,cdr(l),i+1);};json.valueToJSVal=function(v){if(!isList(v))
-return v;if(json.isJSArray(v))
-return json.valuesToJSElements(range(0,v.length),v,0);return json.valuesToJSProperties({},v);};json.valuesToJSProperties=function(o,l){if(isNil(l))
-return o;var token=car(l);if(isTaggedList(token,attribute)){var pv=json.valueToJSVal(attributeValue(token));o['@'+attributeName(token).slice(1)]=pv;}else if(isTaggedList(token,element)){if(elementHasValue(token)){var pv=json.valueToJSVal(elementValue(token));o[elementName(token).slice(1)]=pv;}else{var child={};o[elementName(token).slice(1)]=child;json.valuesToJSProperties(child,elementChildren(token));}}
-return json.valuesToJSProperties(o,cdr(l));};json.writeJSON=function(l){var jsv;if(json.isJSArray(l))
-jsv=json.valuesToJSElements(range(0,l.length),l,0);else
-jsv=json.valuesToJSProperties({},l);var s=json.toJSON(jsv);return mklist(s);}
-json.jsonRequest=function(id,func,params){var r=mklist(mklist("'id",id),mklist("'method",func),mklist("'params",params));return json.writeJSON(valuesToElements(r));};json.jsonResult=function(id,val){return json.writeJSON(valuesToElements(mklist(mklist("'id",id),mklist("'result",val))));};json.jsonResultValue=function(s){var jsres=json.readJSON(s);var res=elementsToValues(jsres);var val=cadr(assoc("'result",res));if(isList(val)&&!json.isJSArray(val))
-return mklist(val);return val;};json.escapeJSONChar=function(c){if(c=="\""||c=="\\")return"\\"+c;if(c=="\b")return"\\b";if(c=="\f")return"\\f";if(c=="\n")return"\\n";if(c=="\r")return"\\r";if(c=="\t")return"\\t";var hex=c.charCodeAt(0).toString(16);if(hex.length==1)return"\\u000"+hex;if(hex.length==2)return"\\u00"+hex;if(hex.length==3)return"\\u0"+hex;return"\\u"+hex;};json.escapeJSONString=function(s){var parts=s.split("");for(var i=0;i<parts.length;i++){var c=parts[i];if(c=='"'||c=='\\'||c.charCodeAt(0)<32||c.charCodeAt(0)>=128)
-parts[i]=json.escapeJSONChar(parts[i]);}
-return"\""+parts.join("")+"\"";};json.toJSON=function(o){if(o==null)
-return"null";if(o.constructor==String)
-return json.escapeJSONString(o);if(o.constructor==Number)
-return o.toString();if(o.constructor==Boolean)
-return o.toString();if(o.constructor==Date)
-return'{javaClass: "java.util.Date", time: '+o.valueOf()+'}';if(o.constructor==Array){var v=[];for(var i=0;i<o.length;i++)
-v.push(json.toJSON(o[i]));return"["+v.join(", ")+"]";}
-var v=[];for(attr in o){if(o[attr]==null)
-v.push("\""+attr+"\": null");else if(typeof o[attr]=="function");else
-v.push(json.escapeJSONString(attr)+": "+json.toJSON(o[attr]));}
-return"{"+v.join(", ")+"}";};var scdl={};scdl.composite=function(l){var cs=namedElementChildren("'composite",l);if(isNil(cs))
-return cs;return car(cs);};scdl.components=function(l){var cs=namedElementChildren("'composite",l);if(isNil(cs))
-return cs;return namedElementChildren("'component",car(cs));};scdl.promotions=function(l){var cs=namedElementChildren("'composite",l);if(isNil(cs))
-return cs;return namedElementChildren("'service",car(cs));};scdl.promote=function(l){var puri=namedAttributeValue("'promote",l);if(isNil(puri))
-return puri;return car(tokens(puri));};scdl.name=function(l){return namedAttributeValue("'name",l);};scdl.documentation=function(l){var d=namedElementChildren("'documentation",l);if(isNil(d))
-return null;if(!elementHasValue(car(d)))
-return null;var v=elementValue(car(d));return v;};scdl.title=function(l){return namedAttributeValue("'title",l);};scdl.style=function(l){return namedAttributeValue("'style",l);};scdl.color=function(l){return namedAttributeValue("'color",l);};scdl.x=function(l){return namedAttributeValue("'x",l);};scdl.y=function(l){return namedAttributeValue("'y",l);};scdl.implementation=function(l){function filterImplementation(v){return isElement(v)&&cadr(v).match("implementation.")!=null;}
-var n=filter(filterImplementation,l);if(isNil(n))
-return null;return car(n);};scdl.implementationType=function(l){return elementName(l).substring(1);};scdl.uri=function(l){return namedAttributeValue("'uri",l);};scdl.align=function(l){return namedAttributeValue("'align",l);};scdl.visible=function(l){return namedAttributeValue("'visible",l);};scdl.clonable=function(l){return namedAttributeValue("'clonable",l);};scdl.services=function(l){return namedElementChildren("'service",l);};scdl.references=function(l){return namedElementChildren("'reference",l);};scdl.bindings=function(l){function filterBinding(v){return isElement(v)&&cadr(v).match("binding.")!=null;}
-return filter(filterBinding,l);};scdl.bindingType=function(l){return elementName(l).substring(1);};scdl.target=function(l){function targetURI(){function bindingsTarget(l){if(isNil(l))
-return null;var u=scdl.uri(car(l));if(!isNil(u))
-return u;return bindingsTarget(cdr(l));}
-var t=namedAttributeValue("'target",l);if(!isNil(t))
-return t;return bindingsTarget(scdl.bindings(l));}
-var turi=targetURI();if(isNil(turi))
-return turi;return car(tokens(turi));};scdl.properties=function(l){return namedElementChildren("'property",l);};scdl.propertyValue=function(l){if(!elementHasValue(l))
-return'';return elementValue(l);};scdl.nameToElementAssoc=function(l){if(isNil(l))
-return l;return cons(mklist(scdl.name(car(l)),car(l)),scdl.nameToElementAssoc(cdr(l)));};var ui={};ui.elementByID=function(node,id){if(node.skipNode==true)
-return null;for(var i in node.childNodes){var child=node.childNodes[i];if(child.id==id)
-return child;var gchild=ui.elementByID(child,id);if(gchild!=null)
-return gchild;}
-return null;};function $(id){if(id==document)
-return document;return ui.elementByID($(document),id);};ui.query=function(url){var u=''+url;var q=u.indexOf('?');return q>=0?u.substring(q+1):'';};ui.fragment=function(url){var u=''+url;var h=u.indexOf('#');return h>=0?u.substring(h+1):'';};ui.pathandparams=function(url){var u=''+url;var ds=u.indexOf('//');var u2=ds>0?u.substring(ds+2):u;var s=u2.indexOf('/');return s>0?u2.substring(s):'';};ui.queryParams=function(url){var qp=new Array();var qs=ui.query(url).split('&');for(var i=0;i<qs.length;i++){var e=qs[i].indexOf('=');if(e>0)
-qp[qs[i].substring(0,e)]=unescape(qs[i].substring(e+1));}
-return qp;};ui.fragmentParams=function(url){var qp=new Array();var qs=ui.fragment(url).split('&');for(var i=0;i<qs.length;i++){var e=qs[i].indexOf('=');if(e>0)
-qp[qs[i].substring(0,e)]=unescape(qs[i].substring(e+1));}
-return qp;};ui.b64img=function(b64){return'data:image/png;base64,'+b64;};ui.declareCSS=function(s){var e=document.createElement('style');e.type='text/css';e.textContent=s;return e;};ui.declareScript=function(s){var e=document.createElement('script');e.type='text/javascript';e.text=s;return e;};ui.innerScripts=function(e){return map(function(s){return s.text;},nodeList(e.getElementsByTagName('script')));};ui.evalScript=function(s){return eval('(function() {\n'+s+'\n})();');};ui.includeScript=function(s){log('include',s);return eval(s);};ui.mobiledetected=false;ui.mobile=false;ui.isMobile=function(){if(ui.mobiledetected)
-return ui.mobile;var ua=navigator.userAgent;if(ua.match(/iPhone/i)||ua.match(/iPad/i)||ua.match(/Android/i)||ua.match(/Blackberry/i)||ua.match(/WebOs/i))
-ui.mobile=true;ui.mobiledetected=true;return ui.mobile;};ui.hometitle=function(host){if(!isNil(window.top.config.hometitle))
-return window.top.config.hometitle;var h=reverse(host.split('.'));var d=isNil(cdr(h))?car(h):cadr(h);return d.substr(0,1).toUpperCase()+d.substr(1);};ui.windowtitle=function(host){if(!isNil(window.top.config.windowtitle))
-return window.top.config.windowtitle;var h=reverse(host.split('.'));var d=isNil(cdr(h))?car(h):cadr(h);return d.substr(0,1).toUpperCase()+d.substr(1);};ui.numpos=function(p){return p==''?0:Number(p.substr(0,p.length-2));};ui.pixpos=function(p){return p+'px';};ui.onorientationchange=function(){window.location.reload();return true;}
-ui.navigate=function(url,win){log('navigate',url,win);if(win=='_blank')
-return window.top.open(url,win);if(win=='_self')
-return window.top.open(url,win);if(win=='_reload'){window.top.location=url;return window.top.location.reload();}
-if(win=='_view'){if(!window.top.onnavigate)
-return window.top.open(url,'_self');return window.top.onnavigate(url);}
-return window.top.open(url,win);}
-ui.ahref=function(loc,target,html){if(target=='_blank')
-return'<a href="'+loc+'" target="_blank">'+html+'</a>';return'<a href="javascript:void(0)" onclick="ui.navigate(\''+loc+'\', \''+target+'\');">'+html+'</a>';};ui.menu=function(name,href,target,hilight){function Menu(){this.content=function(){if(hilight)
-return ui.ahref(href,target,'<span class="tbarsmenu">'+name+'</span>');return ui.ahref(href,target,'<span class="tbaramenu">'+name+'</span>');};}
-return new Menu();};ui.menubar=function(left,right){var bar='<table cellpadding="0" cellspacing="0" width="100%" class="tbar"><tr>'+'<td class="dtbar"><table border="0" cellspacing="0" cellpadding="0"><tr>';for(i in left)
-bar=bar+'<td class="ltbar">'+left[i].content()+'</td>'
-bar=bar+'</tr></table></td>'+'<td class="dtbar"><table border="0" cellpadding="0" cellspacing="0" align="right"><tr>';for(i in right)
-bar=bar+'<td class="'+(i==0?'dtbar':'rtbar')+'">'+right[i].content()+'</td>'
-bar=bar+'</tr></table></td></tr></table>';return bar;};ui.datatable=function(l){function indent(i){if(i==0)
-return'';return'&nbsp;&nbsp;'+indent(i-1);}
-function rows(l,i){if(isNil(l))
-return'';var e=car(l);if(!isList(e))
-return rows(expandElementValues("'value",l),i);if(isList(car(e)))
-return rows(expandElementValues("'value",l),i);if(elementHasValue(e)){var v=elementValue(e);if(!isList(v)){return'<tr><td class="datatdl">'+indent(i)+elementName(e).slice(1)+'</td>'+'<td class="datatdr tdw">'+(v!=null?v:'')+'</td></tr>'+rows(cdr(l),i);}
-return rows(expandElementValues(elementName(e),v),i)+rows(cdr(l),i);}
-return'<tr><td class="datatdl">'+indent(i)+elementName(e).slice(1)+'</td>'+'<td class="datatdr tdw">'+'</td></tr>'+rows(elementChildren(e),i+1)+rows(cdr(l),i);}
-return'<table class="datatable '+(window.name=='dataFrame'?' databg':'')+'" style="width: 100%;">'+rows(l,0)+'</table>';}
-ui.datalist=function(l){function rows(l,i){if(isNil(l))
-return'';var e=car(l);if(!isList(e))
-return rows(expandElementValues("'value",l),i);if(isList(car(e)))
-return rows(expandElementValues("'value",l),i);if(elementHasValue(e)){var v=elementValue(e);if(!isList(v)){return'<tr><td class="datatd tdw">'+(v!=null?v:'')+'</td></tr>'+rows(cdr(l),i);}
-return rows(expandElementValues(elementName(e),v),i)+rows(cdr(l),i);}
-return rows(elementChildren(e),i+1)+rows(cdr(l),i);}
-return'<table class="datatable '+(window.name=='dataFrame'?' databg':'')+'" style="width: 100%;">'+rows(l,0)+'</table>';}
-ui.selectSuggestion=function(node,value){for(;;){node=node.parentNode;if(node.tagName.toLowerCase()=='div')
-break;}
-node.selectSuggestion(value);};ui.hilightSuggestion=function(node,over){if(over)
-node.className='suggestHilighted';node.className='suggestItem';};ui.suggest=function(input,suggestFunction){input.suggest=suggestFunction;input.selectSuggestion=function(value){this.hideSuggestDiv();this.value=value;}
-input.hideSuggestDiv=function(){if(this.suggestDiv!=null){this.suggestDiv.style.visibility='hidden';}}
-input.showSuggestDiv=function(){if(this.suggestDiv==null){this.suggestDiv=document.createElement('div');this.suggestDiv.input=this;this.suggestDiv.className='suggest';input.parentNode.insertBefore(this.suggestDiv,input);this.suggestDiv.style.visibility='hidden';this.suggestDiv.style.zIndex='99';this.suggestDiv.selectSuggestion=function(value){this.input.selectSuggestion(value);}}
-var values=this.suggest();var items='';for(var i=0;i<values.length;i++){if(values[i].indexOf(this.value)==-1)
-continue;if(items.length==0)
-items+='<table class="suggestTable">';items+='<tr><td class="suggestItem" '+'onmouseover="ui.hilightSuggestion(this, true)" onmouseout="ui.hilightSuggestion(this, false)" '+'onmousedown="ui.selectSuggestion(this, \''+values[i]+'\')">'+values[i]+'</td></tr>';}
-if(items.length!=0)
-items+='</table>';this.suggestDiv.innerHTML=items;if(items.length!=0){var node=input;var left=0;var top=0;for(;;){left+=node.offsetLeft;top+=node.offsetTop;node=node.offsetParent;if(node.tagName.toLowerCase()=='body')
-break;}
-this.suggestDiv.style.left=left;this.suggestDiv.style.top=top+input.offsetHeight;this.suggestDiv.style.visibility='visible';}else
-this.suggestDiv.style.visibility='hidden';}
-input.onkeydown=function(event){this.showSuggestDiv();};input.onkeyup=function(event){this.showSuggestDiv();};input.onmousedown=function(event){this.showSuggestDiv();};input.onblur=function(event){setTimeout(function(){input.hideSuggestDiv();},50);};};var JSONClient={};JSONClient.escapeJSONChar=function(c){if(c=="\""||c=="\\")return"\\"+c;if(c=="\b")return"\\b";if(c=="\f")return"\\f";if(c=="\n")return"\\n";if(c=="\r")return"\\r";if(c=="\t")return"\\t";var hex=c.charCodeAt(0).toString(16);if(hex.length==1)return"\\u000"+hex;if(hex.length==2)return"\\u00"+hex;if(hex.length==3)return"\\u0"+hex;return"\\u"+hex;};JSONClient.escapeJSONString=function(s){var parts=s.split("");for(var i=0;i<parts.length;i++){var c=parts[i];if(c=='"'||c=='\\'||c.charCodeAt(0)<32||c.charCodeAt(0)>=128)
-parts[i]=JSONClient.escapeJSONChar(parts[i]);}
-return"\""+parts.join("")+"\"";};JSONClient.toJSON=function(o){if(o==null)
-return"null";if(o.constructor==String)
-return JSONClient.escapeJSONString(o);if(o.constructor==Number)
-return o.toString();if(o.constructor==Boolean)
-return o.toString();if(o.constructor==Date)
-return'{javaClass: "java.util.Date", time: '+o.valueOf()+'}';if(o.constructor==Array){var v=[];for(var i=0;i<o.length;i++)
-v.push(JSONClient.toJSON(o[i]));return"["+v.join(", ")+"]";}
-var v=[];for(attr in o){if(o[attr]==null)
-v.push("\""+attr+"\": null");else if(typeof o[attr]=="function");else
-v.push(JSONClient.escapeJSONString(attr)+": "+JSONClient.toJSON(o[attr]));}
-return"{"+v.join(", ")+"}";};function HTTPBindingClient(name,uri,domain){this.name=name;this.domain=domain;this.uri=uri;this.apply=this.createApplyMethod();}
-HTTPBindingClient.jsonrpcID=1;HTTPBindingClient.prototype.createApplyMethod=function(){var fn=function(){var methodName=arguments[0];var args=[];for(var i=1;i<arguments.length;i++)
-args.push(arguments[i]);var cb=null;if(typeof args[args.length-1]=="function")
-cb=args.pop();var req=HTTPBindingClient.makeJSONRequest(methodName,args,cb);return fn.client.jsonApply(req);};fn.client=this;return fn;};HTTPBindingClient.makeJSONRequest=function(methodName,args,cb){var req={};req.id=HTTPBindingClient.jsonrpcID++;if(cb)
-req.cb=cb;var obj={};obj.id=req.id;obj.method=methodName;obj.params=args;req.data=JSONClient.toJSON(obj);return req;};HTTPBindingClient.jsonResult=function(http){function httpCharset(http){try{var contentType=http.getResponseHeader("Content-Type");var parts=contentType.split(/\s*;\s*/);for(var i=0;i<parts.length;i++){if(parts[i].substring(0,8)=="charset=")
-return parts[i].substring(8,parts[i].length);}}catch(e){}
-return"UTF-8";}
-if(!HTTPBindingClient.charset)
-HTTPBindingClient.charset=httpCharset(http);var obj;eval("obj = "+http.responseText);if(obj.error)
-throw new HTTPBindingClient.Exception(obj.error.code,obj.error.msg);var res=obj.result;return res;};HTTPBindingClient.prototype.jsonApply=function(req){var http=HTTPBindingClient.getHTTPRequest();var hascb=req.cb?true:false;http.open("POST",this.uri,hascb);http.setRequestHeader("Content-Type","application/json-rpc");if(hascb){http.onreadystatechange=function(){if(http.readyState==4){if(http.status==200){var res=null;try{res=HTTPBindingClient.jsonResult(http);try{req.cb(res);}catch(cbe){}}catch(e){try{req.cb(null,e);}catch(cbe){}}}else
-try{req.cb(null,HTTPBindingClient.Exception(http.status,http.statusText));}catch(cbe){}}};http.send(req.data);return req.id;}
-http.send(req.data);if(http.status==200)
-return HTTPBindingClient.jsonResult(http);throw new HTTPBindingClient.Exception(http.status,http.statusText);};HTTPBindingClient.prototype.get=function(id,cb){var u=id?(this.uri?this.uri+'/'+id:id):this.uri;var hascb=cb?true:false;var item=localStorage.getItem(u);if(item!=null&&item!=''){if(!hascb)
-return item;try{cb(item);}catch(cbe){}}
-var http=HTTPBindingClient.getHTTPRequest();http.open("GET",u,hascb);if(hascb){http.onreadystatechange=function(){if(http.readyState==4){if(http.status==200){if(http.getResponseHeader("X-Login")!=null){try{cb(null,new HTTPBindingClient.Exception(403,'X-Login'));}catch(cbe){}}else if(http.responseText==''||http.getResponseHeader("Content-Type")==null){try{cb(null,new HTTPBindingClient.Exception(403,'No-Content'));}catch(cbe){}}else{if(item==null||http.responseText!=item){if(http.responseText!=null){localStorage.setItem(u,http.responseText);}
-try{cb(http.responseText);}catch(cbe){}}}}
-else{if(item==null){try{cb(null,new HTTPBindingClient.Exception(http.status,http.statusText));}catch(cbe){}}}}};http.send(null);return true;}
-http.send(null);if(http.status==200){if(http.getResponseHeader("X-Login")!=null){throw new HTTPBindingClient.Exception(403,'X-Login');}else if(http.responseText==''||http.getResponseHeader("Content-Type")==null){throw new HTTPBindingClient.Exception(403,'No-Content');}
-return http.responseText;}
-throw new HTTPBindingClient.Exception(http.status,http.statusText);};HTTPBindingClient.prototype.getnocache=function(id,cb){var u=id?(this.uri?this.uri+'/'+id:id):this.uri;var hascb=cb?true:false;var http=HTTPBindingClient.getHTTPRequest();http.open("GET",u,hascb);if(hascb){http.onreadystatechange=function(){if(http.readyState==4){if(http.status==200){if(http.getResponseHeader("X-Login")!=null){try{return cb(null,new HTTPBindingClient.Exception(403,'X-Login'));}catch(cbe){}}else if(http.responseText==''||http.getResponseHeader("Content-Type")==null){try{return cb(null,new HTTPBindingClient.Exception(403,'No-Content'));}catch(cbe){}}else{try{cb(http.responseText);}catch(cbe){}}}else{try{cb(null,new HTTPBindingClient.Exception(http.status,http.statusText));}catch(cbe){}}}};http.send(null);return true;}
-http.send(null);if(http.status==200){if(http.getResponseHeader("X-Login")!=null){throw new HTTPBindingClient.Exception(403,'X-Login');}else if(http.responseText==''||http.getResponseHeader("Content-Type")==null){throw new HTTPBindingClient.Exception(403,'No-Content');}
-return http.responseText;}
-throw new HTTPBindingClient.Exception(http.status,http.statusText);};HTTPBindingClient.prototype.post=function(entry,cb){var http=HTTPBindingClient.getHTTPRequest();var hascb=cb?true:false;http.open("POST",this.uri,hascb);http.setRequestHeader("Content-Type","application/atom+xml");if(hascb){http.onreadystatechange=function(){if(http.readyState==4){if(http.status==201){try{cb(http.responseText);}catch(cbe){}}
-else{try{cb(null,new HTTPBindingClient.Exception(http.status,http.statusText));}catch(cbe){}}}};http.send(entry);return true;}
-http.send(entry);if(http.status==201)
-return http.responseText;throw new HTTPBindingClient.Exception(http.status,http.statusText);};HTTPBindingClient.prototype.put=function(id,entry,cb){var u=this.uri+'/'+id;localStorage.setItem(u,entry);var http=HTTPBindingClient.getHTTPRequest();var hascb=cb?true:false;http.open("PUT",u,hascb);http.setRequestHeader("Content-Type","application/atom+xml");if(hascb){http.onreadystatechange=function(){if(http.readyState==4){if(http.status==200){try{cb();}catch(cbe){}}else{try{cb(new HTTPBindingClient.Exception(http.status,http.statusText));}catch(cbe){}}}};http.send(entry);return true;}
-http.send(entry);if(http.status==200)
-return true;throw new HTTPBindingClient.Exception(http.status,http.statusText);};HTTPBindingClient.prototype.del=function(id,cb){var u=this.uri+'/'+id;localStorage.removeItem(u);var http=HTTPBindingClient.getHTTPRequest();var hascb=cb?true:false;http.open("DELETE",u,hascb);if(cb){http.onreadystatechange=function(){if(http.readyState==4){if(http.status==200){try{cb();}catch(cbe){}}
-else{try{cb(new HTTPBindingClient.Exception(http.status,http.statusText));}catch(cbe){}}}};http.send(null);return true;}
-http.send(null);if(http.status==200)
-return true;throw new HTTPBindingClient.Exception(http.status,http.statusText);};HTTPBindingClient.Exception=function(code,message){this.name="HTTPBindingClientException";this.code=code;this.message=message;};HTTPBindingClient.Exception.prototype=new Error();HTTPBindingClient.Exception.prototype.toString=function(){return this.name+": "+this.message;};HTTPBindingClient.msxmlNames=["MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"];HTTPBindingClient.getHTTPRequest=function(){if(HTTPBindingClient.httpFactory)
-return HTTPBindingClient.httpFactory();try{HTTPBindingClient.httpFactory=function(){return new XMLHttpRequest();};return HTTPBindingClient.httpFactory();}catch(e){}
-for(var i=0;i<HTTPBindingClient.msxmlNames.length;i++){try{HTTPBindingClient.httpFactory=function(){return new ActiveXObject(HTTPBindingClient.msxmlNames[i]);};return HTTPBindingClient.httpFactory();}catch(e){}}
-HTTPBindingClient.httpFactory=null;throw new HTTPBindingClient.Exception(0,"Can't create XMLHttpRequest object");};var sca={};sca.httpclient=function(name,uri,domain){return new HTTPBindingClient(name,uri,domain);};sca.component=function(name,domain){if(!domain)
-return new HTTPBindingClient(name,'/c/'+name,domain);return new HTTPBindingClient(name,'/a/'+domain+'/c/'+name,domain);};sca.reference=function(comp,rname){if(!comp.domain)
-return new HTTPBindingClient(comp.name+'/'+rname,'/r/'+comp.name+'/'+rname,comp.domain);return new HTTPBindingClient(comp.name+'/'+rname,'/a/'+comp.domain+'/r/'+comp.name+'/'+rname,comp.domain);};sca.defun=function(ref){function defapply(name){return function(){var args=new Array();args[0]=name;for(i=0,n=arguments.length;i<n;i++)
-args[i+1]=arguments[i];return this.apply.apply(this,args);};}
-for(f=1;f<arguments.length;f++){var fn=arguments[f];ref[fn]=defapply(fn);}
-return ref;};
diff --git a/modules/js/htdocs/ui-min.css b/modules/js/htdocs/ui-min.css
deleted file mode 100644
index d8d8863..0000000
--- a/modules/js/htdocs/ui-min.css
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
- *   
- * 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.
- */
-body{margin-top:0px;margin-bottom:2px;margin-left:2px;margin-right:2px;font-family:"Helvetica Neue", Helvetica;font-style:normal;font-variant:normal;font-size:13px;-webkit-text-size-adjust:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-user-select:none;}
-.delayed{visibility:hidden;}
-.devicewidth{position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:hidden;}
-.mainbodydiv{position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:hidden;}
-.bodydiv{position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:hidden;}
-.viewcontainer3dm{-webkit-perspective:1000;}
-.viewcontainer3d{}
-.leftviewloading3dm{position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:visible;-webkit-transform:translate3d(100%, 0px, 0) rotateY(0deg);-webkit-backface-visibility:hidden;background-color:#ffffff;-moz-transform:translate(100%, 0px);-ms-transform:translate(100%, 0px);transform:translate(100%, 0px);}
-.rightviewloading3dm{position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:visible;-webkit-transform:translate3d(-100%, 0px, 0) rotateY(0deg);-webkit-backface-visibility:hidden;background-color:#ffffff;-moz-transform:translate(-100%, 0px);-ms-transform:translate(-100%, 0px);transform:translate(-100%, 0px);}
-.flipviewloading3dm{position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:visible;-webkit-transform:translate3d(0px, 0px, 0) rotateY(180deg);-webkit-backface-visibility:hidden;background-color:#ffffff;-moz-transform:translate(100%, 0px);-ms-transform:translate(100%, 0px);transform:translate(100%, 0px);}
-.viewloading3d{position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:visible;visibility:hidden;-webkit-transform:translate3d(100%, 0px, 0) rotateY(0deg);-webkit-backface-visibility:hidden;background-color:#ffffff;-moz-transform:translate(100%, 0px);-ms-transform:translate(100%, 0px);transform:translate(100%, 0px);}
-.viewloaded3dm{position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:visible;-webkit-transition:-webkit-transform 0.5s ease-in-out;-moz-transition:-moz-transform 0.5s ease-in-out;-ms-transition:-ms-transform 0.5s ease-in-out;transition:transform 0.5s ease-in-out;-webkit-transform:translate3d(0px, 0px, 0) rotateY(0deg);-webkit-backface-visibility:hidden;background-color:#ffffff;-moz-transform:translate(0px, 0px);-ms-transform:translate(0px, 0px);transform:translate(0px, 0px);}
-.viewloaded3d{position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:visible;-webkit-transform:translate3d(0px, 0px, 0) rotateY(0deg);-webkit-backface-visibility:hidden;background-color:#ffffff;-moz-transform:translate(0px, 0px);-ms-transform:translate(0px, 0px);transform:translate(0px, 0px);}
-.viewunloading3dm{position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:visible;-webkit-transform:translate3d(0px, 0px, 0) rotateY(0deg);-webkit-backface-visibility:hidden;background-color:#ffffff;-moz-transform:translate(0px, 0px);-ms-transform:translate(0px, 0px);transform:translate(0px, 0px);}
-.leftviewunloaded3dm{position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:visible;-webkit-transition:-webkit-transform 0.5s ease-in-out;-moz-transition:-moz-transform 0.5s ease-in-out;-ms-transition:-ms-transform 0.5s ease-in-out;transition:transform 0.5s ease-in-out;-webkit-transform:translate3d(-100%, 0px, 0px) rotateY(0deg);-webkit-backface-visibility:hidden;background-color:#ffffff;-moz-transform:translate(-100%, 0px);-ms-transform:translate(-100%, 0px);transform:translate(-100%, 0px);}
-.rightviewunloaded3dm{position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:visible;-webkit-transition:-webkit-transform 0.5s ease-in-out;-moz-transition:-moz-transform 0.5s ease-in-out;-ms-transition:-ms-transform 0.5s ease-in-out;transition:transform 0.5s ease-in-out;-webkit-transform:translate3d(100%, 0px, 0) rotateY(0deg);-webkit-backface-visibility:hidden;background-color:#ffffff;-moz-transform:translate(100%, 0px);-ms-transform:translate(100%, 0px);transform:translate(100%, 0px);}
-.flipviewunloaded3dm{position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:visible;-webkit-transition:-webkit-transform 0.5s ease-in-out;-moz-transition:-moz-transform 0.5s ease-in-out;-ms-transition:-ms-transform 0.5s ease-in-out;transition:transform 0.5s ease-in-out;-webkit-transform:translate3d(0px, 0px, 0) rotateY(-180deg);-webkit-backface-visibility:hidden;background-color:#ffffff;-moz-transform:translate(0px, 0px);-ms-transform:translate(0px, 0px);transform:translate(0px, 0px);}
-table{border:0px;border-collapse:collapse;border-color:#a2bae7;border-style:solid;font-family:"Helvetica Neue", Helvetica;font-style:normal;font-variant:normal;font-size:13px;overflow:visible;}
-.trb{border-bottom:1px;border-bottom-style:solid;border-color:#dcdcdc;}
-th{font-weight:bold;background-color:#d4e6fc;color:#000000;height:18px;text-align:left;padding-left:2px;padding-right:8px;padding-top:0px;padding-bottom:0px;vertical-align:middle;white-space:nowrap;border-top:1px;border-bottom:1px;border-left:1px;border-right:1px;border-style:solid;border-top-color:#a2bae7;border-bottom-color:#d1d3d4;border-left-color:#a2bae7;border-right-color:#a2bae7;overflow:hidden;}
-.section{font-weight:bold;background-color:#d4e6fc;color:#000000;height:24px;padding-top:1px;padding-bottom:0px;padding-left:2px;padding-right:2px;border-top:1px;border-bottom:1px;border-left:0px;border-right:0px;border-style:solid;border-top-color:#a2bae7;border-bottom-color:#d1d3d4;border-left-color:#a2bae7;border-right-color:#a2bae7;overflow:hidden;}
-.hsection{width:100%;height:50px;border-top:0px;border-bottom:0px;border-left:0px;border-right:0px;border-style:solid;border-bottom-color:#000000;background-color:#ffffff;padding:0px;margin-bottom:0px;margin-left:auto;margin-right:auto;text-align:center;}
-.fsection{width:100%;height:50px;border-top:0px;border-bottom:0px;border-left:0px;border-right:0px;border-style:solid;border-top-color:#a2bae7;padding:0px;margin-top:0px;margin-left:auto;margin-right:auto;text-align:center;}
-.text{padding-top:3px;padding-bottom:4px;vertical-align:middle;white-space:nowrap;}
-.thl{border-left:0px;}
-.thr{border-right:0px;}
-.ths{padding:0px;}
-td{padding-left:2px;padding-top:2px;padding-right:8px;white-space:nowrap;vertical-align:middle;border:0px;}
-.tdl{border-right:1px;border-style:solid;border-color:#a2bae7;width:10px;}
-.tdr{border-left:1px;border-style:solid;border-color:#a2bae7;}
-.tdw{padding-left:2px;padding-top:2px;padding-right:8px;white-space:normal;vertical-align:middle;}
-.datatd{border-top:1px;border-bottom:1px;border-style:solid;border-color:#dcdcdc;width:10px;vertical-align:middle;}
-.datatdl{border-right:1px;border-top:1px;border-bottom:1px;border-style:solid;border-color:#dcdcdc;width:10px;vertical-align:middle;}
-.datatdltop{border-right:1px;border-top:1px;border-bottom:1px;border-style:solid;border-color:#dcdcdc;width:10px;vertical-align:top;}
-.datatdr{border-left:1px;border-top:1px;border-bottom:1px;border-style:solid;border-color:#dcdcdc;vertical-align:middle;}
-.datatable{border-top:1px;border-bottom:1px;border-style:solid;border-color:#dcdcdc;overflow:visible;}
-.databg{opacity:.6;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";filter:alpha(opacity=60);}
-.guide{border:1px;border-style:solid;border-color:#c0c0c0;}
-iframe{border:0px;margin:0px;padding:0px;}
-.fakeframe{padding:3px;background-color:#dcdcdc;color:#000000;}
-input{vertical-align:middle;font-family:"Helvetica Neue", Helvetica;font-style:normal;font-variant:normal;font-size:13px;-webkit-text-size-adjust:100%;}
-textarea{font-family:"Helvetica Neue", Helvetica;font-style:normal;font-variant:normal;font-size:13px;overflow:auto;resize:none;}
-.editable{background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-size:inherit;font-weight:inherit;padding:0px;margin:0px;overflow:auto;resize:none;outline:none;-webkit-appearance:none;-moz-outline-style:none;-webkit-text-size-adjust:100%;border:0px;}
-a:link{color:#598edd;text-decoration:none;white-space:nowrap;}
-a:visited{color:#598edd;text-decoration:none;white-space:nowrap;}
-.amenu{color:#598edd;text-decoration:none;white-space:nowrap;}
-.smenu{font-weight:bold;color:#000000;text-decoration:none;white-space:nowrap;}
-h1{font-size:150%;font-weight:bold;vertical-align:middle;margin-top:5px;margin-bottom:5px;margin-left:2px;margin-right:2px;white-space:nowrap;}
-h2{font-size:120%;font-weight:bold;vertical-align:middle;margin-top:5px;margin-bottom:5px;margin-left:2px;margin-right:2px;white-space:nowrap;}
-.hd1{font-size:150%;font-weight:bold;white-space:nowrap;}
-.hd2{font-size:120%;font-weight:bold;white-space:nowrap;}
-img{border:0px;}
-.imgbutton{width:142px;height:64px;margin-left:20px;margin-right:20px;padding:0px;border:1px;cursor:pointer;}
-.toolbutton{font-weight:bold;font-size:16px;display:inline-block;width:24px;height:20px;padding:0px;vertical-align:middle;text-align:center;margin-left:0px;margin-right:0px;padding-left:0px;padding-right:0px;padding-top:0px;padding-bottom:0px;}
-.greenbutton{-webkit-border-radius:4px;border-radius:4px;background:#96d333;background:-moz-linear-gradient(top, #f8f8f8 0%, #96d333 80%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#96d333));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#96d333',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#96d333 80%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;cursor:pointer;}
-.tgreenbutton{-webkit-border-radius:4px;border-radius:4px;background:#96d333;background:-moz-linear-gradient(top, #f8f8f8 0%, #96d333 80%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#96d333));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#96d333',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#96d333 80%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;cursor:pointer;}
-.bluebutton{-webkit-border-radius:4px;border-radius:4px;background:#598edd;background:-moz-linear-gradient(top, #f8f8f8 0%, #598edd 80%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#598edd));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#598edd',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#598edd 80%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;cursor:pointer;}
-.redbutton{-webkit-border-radius:4px;border-radius:4px;background:#d03f41;background:-moz-linear-gradient(top, #f8f8f8 0%, #d03f41 80%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#d03f41));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#d03f41',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#d03f41 80%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;cursor:pointer;}
-.orangebutton{-webkit-border-radius:4px;border-radius:4px;background:#ffbb00;background:-moz-linear-gradient(top, #f8f8f8 0%, #ffbb00 80%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#ffbb00));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#ffbb00',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#ffbb00 80%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;cursor:pointer;}
-.graybutton{-webkit-border-radius:4px;border-radius:4px;background:#dcdcdc;background:-moz-linear-gradient(top, #f8f8f8 0%, #dcdcdc 80%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#dcdcdc));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#dcdcdc',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#dcdcdc 80%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;margin:2px;cursor:pointer;}
-.tbar{margin:0px;width:100%;padding-top:0px;padding-left:0px;padding-right:0px;padding-bottom:0px;border-collapse:separate;background-color:#2c2c2c;}
-.ltbar{padding-left:2px;padding-right:6px;padding-top:3px;padding-bottom:4px;white-space:nowrap;vertical-align:middle;}
-.dtbar{padding-left:0px;padding-right:0px;padding-top:3px;padding-bottom:4px;white-space:nowrap;vertical-align:middle;text-align:right;}
-.rtbar{padding-left:6px;padding-right:2px;padding-top:3px;padding-bottom:4px;white-space:nowrap;vertical-align:middle;text-align:right;}
-.tbaramenu{color:#cccccc;text-decoration:none;white-space:nowrap;vertical-align:middle;}
-.tbarsmenu{font-weight:bold;color:#ffffff;text-decoration:none;white-space:nowrap;vertical-align:middle;}
-.suggest{background-color:#d4e6fc;color:#598edd;border-top:1px;border-bottom:1px;border-left:1px;border-right:1px;border-style:solid;border-top-color:#a2bae7;border-bottom-color:#d1d3d4;border-left-color:#d1d3d4;border-right-color:#d1d3d4;position:absolute;overflow:auto;overflow-x:hidden;padding:0px;margin:0px;cursor:default;}
-.suggestTable{border:0px;border-collapse:separate;padding-left:5px;padding-right:5px;padding-top:2px;padding-bottom:2px;margin:0px;}
-.suggestItem{padding-left:2px;padding-top:0px;padding-bottom:0px;padding-right:2px;vertical-align:middle;background-color:#d4e6fc;color:#598edd;}
-.suggestHilighted{padding-left:2px;padding-top:0px;padding-bottom:0px;padding-right:2px;vertical-align:middle;background-color:#598edd;color:#d4e6fc;}
-.svgtitle{margin:0px;padding:0px;font-family:"Helvetica Neue", Helvetica;font-style:normal;font-variant:normal;font-size:10px;cursor:default;}
diff --git a/ubuntu/ubuntu-install b/ubuntu/ubuntu-install
index c0e8666..0db4fa5 100755
--- a/ubuntu/ubuntu-install
+++ b/ubuntu/ubuntu-install
@@ -300,6 +300,16 @@
 fi
 cd $build
 
+# Build Google Page Speed
+curl -OL https://dl-ssl.google.com/page-speed/sdk/current/page-speed-sdk.zip
+unzip page-speed-sdk.zip
+cd page-speed-1.9
+make builddir=$build/page-speed-1.9-bin
+if [ "$?" != "0" ]; then
+    exit $?
+fi
+cd $build
+
 # Build Apache Nuvem
 git clone git://git.apache.org/nuvem.git
 if [ "$?" != "0" ]; then
@@ -311,7 +321,7 @@
 git clone git://git.apache.org/tuscany-sca-cpp.git
 cd tuscany-sca-cpp
 ./bootstrap
-./configure --prefix=$build/tuscany-sca-cpp-bin --with-curl=$build/curl-7.19.5-bin --with-apr=$build/apr-1.4.x-bin --with-httpd=$build/httpd-2.3.10-bin --with-memcached=$build/memcached-1.4.7-bin --with-tinycdb=$build/tinycdb-0.77-bin --with-js-include=$build/js-1.8.5-bin/include/js --with-js-lib=$build/js-1.8.5-bin/lib --with-libcloud=$build/libcloud-0.4.2-bin --enable-threads --enable-python --with-libxml2=$build/libxml2-2.7.7-bin --enable-chat --with-libstrophe=$build/libstrophe-bin --enable-log --with-thrift=$build/thrift-0.2.0-bin --with-scribe=$build/scribe-2.2-bin --enable-openid --with-mod-auth-openid=$build/mod-auth-openid-bin --enable-oauth --with-liboauth=$build/liboauth-0.9.1-bin --enable-mod-security --with-mod-security=$build/modsecurity-apache-2.6.1-bin
+./configure --prefix=$build/tuscany-sca-cpp-bin --with-curl=$build/curl-7.19.5-bin --with-apr=$build/apr-1.4.x-bin --with-httpd=$build/httpd-2.3.10-bin --with-memcached=$build/memcached-1.4.7-bin --with-tinycdb=$build/tinycdb-0.77-bin --with-js-include=$build/js-1.8.5-bin/include/js --with-js-lib=$build/js-1.8.5-bin/lib --enable-pagespeed --with-pagespeed=$build/page-speed-1.9-bin --with-libcloud=$build/libcloud-0.4.2-bin --enable-threads --enable-python --with-libxml2=$build/libxml2-2.7.7-bin --enable-chat --with-libstrophe=$build/libstrophe-bin --enable-log --with-thrift=$build/thrift-0.2.0-bin --with-scribe=$build/scribe-2.2-bin --enable-openid --with-mod-auth-openid=$build/mod-auth-openid-bin --enable-oauth --with-liboauth=$build/liboauth-0.9.1-bin --enable-mod-security --with-mod-security=$build/modsecurity-apache-2.6.1-bin
 make
 make install
 if [ "$?" != "0" ]; then
@@ -320,8 +330,8 @@
 cd $build
 
 # Create src archive
-tar czf tuscany-sca-cpp-1.0-src.tar.gz apache-libcloud-incubating-0.4.2 apache-libcloud-incubating-0.4.2.tar.bz2 apr-1.4.x apr-1.4.x-bin curl-7.19.5 curl-7.19.5-bin curl-7.19.5.tar.gz expat-2.0.1 expat-2.0.1-bin expat-2.0.1.tar.gz htmltidy-bin httpd-2.3.10 httpd-2.3.10-alpha.tar.gz httpd-2.3.10-bin js-1.8.5-bin js-1.8.5 js185-1.0.0.tar.gz libcloud-0.4.2-bin liboauth-0.9.1 liboauth-0.9.1-bin liboauth-0.9.1.tar.gz libopkele libopkele-bin libstrophe libstrophe-bin libxml2-2.7.7 libxml2-2.7.7-bin libxml2-sources-2.7.7.tar.gz memcached-1.4.7 memcached-1.4.7-bin memcached-1.4.7.tar.gz mod_auth_openid mod-auth-openid-bin modsecurity-apache_2.6.1 modsecurity-apache-2.6.1-bin modsecurity-apache_2.6.1.tar.gz modsecurity-crs_2.2.1 modsecurity-crs_2.2.1.tar.gz nspr-4.8.8-bin nspr-4.8.8 nspr-4.8.8.tar.gz nuvem scribe scribe-2.2-bin scribe-2.2.tar.gz thrift-0.2.0 thrift-0.2.0-bin thrift-0.2.0-incubating.tar.gz tidy tinycdb-0.77 tinycdb-0.77-bin tinycdb_0.77.tar.gz tuscany-sca-cpp tuscany-sca-cpp-bin
+tar czf tuscany-sca-cpp-1.0-src.tar.gz apache-libcloud-incubating-0.4.2 apache-libcloud-incubating-0.4.2.tar.bz2 apr-1.4.x apr-1.4.x-bin curl-7.19.5 curl-7.19.5-bin curl-7.19.5.tar.gz expat-2.0.1 expat-2.0.1-bin expat-2.0.1.tar.gz htmltidy-bin httpd-2.3.10 httpd-2.3.10-alpha.tar.gz httpd-2.3.10-bin js-1.8.5-bin js-1.8.5 js185-1.0.0.tar.gz libcloud-0.4.2-bin liboauth-0.9.1 liboauth-0.9.1-bin liboauth-0.9.1.tar.gz libopkele libopkele-bin libstrophe libstrophe-bin libxml2-2.7.7 libxml2-2.7.7-bin libxml2-sources-2.7.7.tar.gz memcached-1.4.7 memcached-1.4.7-bin memcached-1.4.7.tar.gz mod_auth_openid mod-auth-openid-bin modsecurity-apache_2.6.1 modsecurity-apache-2.6.1-bin modsecurity-apache_2.6.1.tar.gz modsecurity-crs_2.2.1 modsecurity-crs_2.2.1.tar.gz nspr-4.8.8-bin nspr-4.8.8 nspr-4.8.8.tar.gz nuvem page-speed-1.9 page-speed-1.9-bin page-speed-sdk.zip scribe scribe-2.2-bin scribe-2.2.tar.gz thrift-0.2.0 thrift-0.2.0-bin thrift-0.2.0-incubating.tar.gz tidy tinycdb-0.77 tinycdb-0.77-bin tinycdb_0.77.tar.gz tuscany-sca-cpp tuscany-sca-cpp-bin
 
 # Create bin archive
-tar czf tuscany-sca-cpp-1.0.tar.gz apr-1.4.x-bin curl-7.19.5-bin expat-2.0.1-bin htmltidy-bin httpd-2.3.10-bin js-1.8.5-bin libcloud-0.4.2-bin liboauth-0.9.1-bin libopkele-bin libstrophe-bin libxml2-2.7.7-bin memcached-1.4.7-bin mod-auth-openid-bin modsecurity-apache-2.6.1-bin nspr-4.8.8-bin nuvem/nuvem-parallel scribe-2.2-bin thrift-0.2.0-bin tinycdb-0.77-bin tuscany-sca-cpp tuscany-sca-cpp-bin
+tar czf tuscany-sca-cpp-1.0.tar.gz apr-1.4.x-bin curl-7.19.5-bin expat-2.0.1-bin htmltidy-bin httpd-2.3.10-bin js-1.8.5-bin libcloud-0.4.2-bin liboauth-0.9.1-bin libopkele-bin libstrophe-bin libxml2-2.7.7-bin memcached-1.4.7-bin mod-auth-openid-bin modsecurity-apache-2.6.1-bin nspr-4.8.8-bin nuvem/nuvem-parallel page-speed-1.9-bin scribe-2.2-bin thrift-0.2.0-bin tinycdb-0.77-bin tuscany-sca-cpp tuscany-sca-cpp-bin
 
diff --git a/ubuntu/ubuntu-install-all b/ubuntu/ubuntu-install-all
index 86c06db..4132e15 100755
--- a/ubuntu/ubuntu-install-all
+++ b/ubuntu/ubuntu-install-all
@@ -370,6 +370,16 @@
 fi
 cd $build
 
+# Build Google Page Speed
+curl -OL https://dl-ssl.google.com/page-speed/sdk/current/page-speed-sdk.zip
+unzip page-speed-sdk.zip
+cd page-speed-1.9
+make
+if [ "$?" != "0" ]; then
+    exit $?
+fi
+cd $build
+
 # Build Apache Nuvem
 git clone git://git.apache.org/nuvem.git
 if [ "$?" != "0" ]; then
@@ -381,7 +391,7 @@
 git clone git://git.apache.org/tuscany-sca-cpp.git
 cd tuscany-sca-cpp
 ./bootstrap
-./configure --prefix=$build/tuscany-sca-cpp-bin --with-curl=$build/curl-7.19.5-bin --with-apr=$build/apr-1.4.x-bin --with-httpd=$build/httpd-2.3.10-bin --with-memcached=$build/memcached-1.4.7-bin --with-tinycdb=$build/tinycdb-0.77-bin --with-js-include=$build/js-1.8.5-bin/include/js --with-js-lib=$build/js-1.8.5-bin/lib --with-libcloud=$build/libcloud-0.4.2-bin --enable-threads --enable-python --enable-gae --with-gae=$build/google_appengine --enable-java --with-java=/usr/lib/jvm/java-6-openjdk --enable-webservice --with-libxml2=$build/libxml2-2.7.7-bin --with-axis2c=$build/axis2c-1.6.0-bin --enable-queue --with-qpidc=$build/qpidc-0.6-bin --enable-chat --with-libstrophe=$build/libstrophe-bin --with-vysper=$build/vysper-0.6 --enable-sqldb --with-pgsql=$build/postgresql-9.0.3-bin --enable-log --with-thrift=$build/thrift-0.2.0-bin --with-scribe=$build/scribe-2.2-bin --enable-openid --with-mod-auth-openid=$build/mod-auth-openid-bin --enable-oauth --with-liboauth=$build/liboauth-0.9.1-bin --enable-mod-security --with-mod-security=$build/modsecurity-apache-2.6.1-bin
+./configure --prefix=$build/tuscany-sca-cpp-bin --with-curl=$build/curl-7.19.5-bin --with-apr=$build/apr-1.4.x-bin --with-httpd=$build/httpd-2.3.10-bin --with-memcached=$build/memcached-1.4.7-bin --with-tinycdb=$build/tinycdb-0.77-bin --with-js-include=$build/js-1.8.5-bin/include/js --with-js-lib=$build/js-1.8.5-bin/lib --enable-pagespeed --with-pagespeed=$build/page-speed-1.9-bin --with-libcloud=$build/libcloud-0.4.2-bin --enable-threads --enable-python --enable-gae --with-gae=$build/google_appengine --enable-java --with-java=/usr/lib/jvm/java-6-openjdk --enable-webservice --with-libxml2=$build/libxml2-2.7.7-bin --with-axis2c=$build/axis2c-1.6.0-bin --enable-queue --with-qpidc=$build/qpidc-0.6-bin --enable-chat --with-libstrophe=$build/libstrophe-bin --with-vysper=$build/vysper-0.6 --enable-sqldb --with-pgsql=$build/postgresql-9.0.3-bin --enable-log --with-thrift=$build/thrift-0.2.0-bin --with-scribe=$build/scribe-2.2-bin --enable-openid --with-mod-auth-openid=$build/mod-auth-openid-bin --enable-oauth --with-liboauth=$build/liboauth-0.9.1-bin --enable-mod-security --with-mod-security=$build/modsecurity-apache-2.6.1-bin
 make
 make install
 if [ "$?" != "0" ]; then
@@ -390,8 +400,8 @@
 cd $build
 
 # Create src archive
-tar czf tuscany-sca-cpp-all-1.0-src.tar.gz apache-libcloud-incubating-0.4.2 apache-libcloud-incubating-0.4.2.tar.bz2 apr-1.4.x apr-1.4.x-bin axis2c-1.6.0-bin axis2c-src-1.6.0 axis2c-src-1.6.0.tar.gz curl-7.19.5 curl-7.19.5-bin curl-7.19.5.tar.gz expat-2.0.1 expat-2.0.1-bin expat-2.0.1.tar.gz google_appengine google_appengine_1.4.0.zip htmltidy-bin httpd-2.3.10 httpd-2.3.10-alpha.tar.gz httpd-2.3.10-bin js-1.8.5-bin js-1.8.5 js185-1.0.0.tar.gz libcloud-0.4.2-bin liboauth-0.9.1 liboauth-0.9.1-bin liboauth-0.9.1.tar.gz libopkele libopkele-bin libstrophe libstrophe-bin libxml2-2.7.7 libxml2-2.7.7-bin libxml2-sources-2.7.7.tar.gz memcached-1.4.7 memcached-1.4.7-bin memcached-1.4.7.tar.gz mod_auth_openid mod-auth-openid-bin modsecurity-apache_2.6.1 modsecurity-apache-2.6.1-bin modsecurity-apache_2.6.1.tar.gz modsecurity-crs_2.2.1 modsecurity-crs_2.2.1.tar.gz nspr-4.8.8-bin nspr-4.8.8 nspr-4.8.8.tar.gz nuvem postgresql-9.0.3 postgresql-9.0.3-bin postgresql-9.0.3.tar.gz qpidc-0.6 qpidc-0.6-bin qpid-cpp-0.6.tar.gz scribe scribe-2.2-bin scribe-2.2.tar.gz thrift-0.2.0 thrift-0.2.0-bin thrift-0.2.0-incubating.tar.gz tidy tinycdb-0.77 tinycdb-0.77-bin tinycdb_0.77.tar.gz tuscany-sca-cpp tuscany-sca-cpp-bin vysper-0.6 vysper-0.6-bin.tar.gz
+tar czf tuscany-sca-cpp-all-1.0-src.tar.gz apache-libcloud-incubating-0.4.2 apache-libcloud-incubating-0.4.2.tar.bz2 apr-1.4.x apr-1.4.x-bin axis2c-1.6.0-bin axis2c-src-1.6.0 axis2c-src-1.6.0.tar.gz curl-7.19.5 curl-7.19.5-bin curl-7.19.5.tar.gz expat-2.0.1 expat-2.0.1-bin expat-2.0.1.tar.gz google_appengine google_appengine_1.4.0.zip htmltidy-bin httpd-2.3.10 httpd-2.3.10-alpha.tar.gz httpd-2.3.10-bin js-1.8.5-bin js-1.8.5 js185-1.0.0.tar.gz libcloud-0.4.2-bin liboauth-0.9.1 liboauth-0.9.1-bin liboauth-0.9.1.tar.gz libopkele libopkele-bin libstrophe libstrophe-bin libxml2-2.7.7 libxml2-2.7.7-bin libxml2-sources-2.7.7.tar.gz memcached-1.4.7 memcached-1.4.7-bin memcached-1.4.7.tar.gz mod_auth_openid mod-auth-openid-bin modsecurity-apache_2.6.1 modsecurity-apache-2.6.1-bin modsecurity-apache_2.6.1.tar.gz modsecurity-crs_2.2.1 modsecurity-crs_2.2.1.tar.gz nspr-4.8.8-bin nspr-4.8.8 nspr-4.8.8.tar.gz nuvem page-speed-1.9 page-speed-1.9-bin page-speed-sdk.zip postgresql-9.0.3 postgresql-9.0.3-bin postgresql-9.0.3.tar.gz qpidc-0.6 qpidc-0.6-bin qpid-cpp-0.6.tar.gz scribe scribe-2.2-bin scribe-2.2.tar.gz thrift-0.2.0 thrift-0.2.0-bin thrift-0.2.0-incubating.tar.gz tidy tinycdb-0.77 tinycdb-0.77-bin tinycdb_0.77.tar.gz tuscany-sca-cpp tuscany-sca-cpp-bin vysper-0.6 vysper-0.6-bin.tar.gz
 
 # Create bin archive
-tar czf tuscany-sca-cpp-all-1.0.tar.gz apr-1.4.x-bin axis2c-1.6.0-bin curl-7.19.5-bin expat-2.0.1-bin google_appengine htmltidy-bin httpd-2.3.10-bin js-1.8.5-bin libcloud-0.4.2-bin liboauth-0.9.1-bin libopkele-bin libstrophe-bin libxml2-2.7.7-bin memcached-1.4.7-bin mod-auth-openid-bin modsecurity-apache-2.6.1-bin nspr-4.8.8-bin nuvem/nuvem-parallel postgresql-9.0.3-bin qpidc-0.6-bin scribe-2.2-bin thrift-0.2.0-bin tinycdb-0.77-bin tuscany-sca-cpp tuscany-sca-cpp-bin vysper-0.6
+tar czf tuscany-sca-cpp-all-1.0.tar.gz apr-1.4.x-bin axis2c-1.6.0-bin curl-7.19.5-bin expat-2.0.1-bin google_appengine htmltidy-bin httpd-2.3.10-bin js-1.8.5-bin libcloud-0.4.2-bin liboauth-0.9.1-bin libopkele-bin libstrophe-bin libxml2-2.7.7-bin memcached-1.4.7-bin mod-auth-openid-bin modsecurity-apache-2.6.1-bin nspr-4.8.8-bin nuvem/nuvem-parallel page-speed-1.9-bin postgresql-9.0.3-bin qpidc-0.6-bin scribe-2.2-bin thrift-0.2.0-bin tinycdb-0.77-bin tuscany-sca-cpp tuscany-sca-cpp-bin vysper-0.6