You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ea...@apache.org on 2020/03/05 22:50:15 UTC

[qpid-dispatch] branch master updated: DISPATCH-1524 Remove hawtio console

This is an automated email from the ASF dual-hosted git repository.

eallen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git


The following commit(s) were added to refs/heads/master by this push:
     new 6d7b421  DISPATCH-1524 Remove hawtio console
6d7b421 is described below

commit 6d7b4219055da30404a0ebbaddb350febb0275b0
Author: Ernest Allen <ea...@redhat.com>
AuthorDate: Thu Mar 5 17:49:57 2020 -0500

    DISPATCH-1524 Remove hawtio console
---
 LICENSE                                            |   25 -
 console/CMakeLists.txt                             |   23 -
 console/hawtio/README.md                           |   86 -
 console/hawtio/pom.xml                             |  314 ---
 console/hawtio/src/main/assembly/META-INF/LICENSE  |  234 --
 console/hawtio/src/main/assembly/META-INF/NOTICE   |    6 -
 .../qpid/dispatch/PluginContextListener.java       |   57 -
 console/hawtio/src/main/resources/WEB-INF/web.xml  |   55 -
 console/hawtio/src/main/resources/log4j.properties |   25 -
 console/hawtio/src/main/webapp/index.html          |   26 -
 .../hawtio/src/main/webapp/plugin/css/brokers.ttf  |  Bin 2272 -> 0 bytes
 .../hawtio/src/main/webapp/plugin/css/dispatch.css |  726 -----
 .../main/webapp/plugin/css/font-awesome.min.css    |    4 -
 .../src/main/webapp/plugin/css/jquery-ui.css       |  464 ----
 .../src/main/webapp/plugin/css/jquery.tipsy.css    |  126 -
 .../hawtio/src/main/webapp/plugin/css/plugin.css   |  994 -------
 .../webapp/plugin/fonts/fontawesome-webfont.woff   |  Bin 83588 -> 0 bytes
 .../webapp/plugin/fonts/fontawesome-webfont.woff2  |  Bin 66624 -> 0 bytes
 .../src/main/webapp/plugin/html/qdrCharts.html     |   82 -
 .../src/main/webapp/plugin/html/qdrConnect.html    |   97 -
 .../src/main/webapp/plugin/html/qdrLayout.html     |   26 -
 .../src/main/webapp/plugin/html/qdrList.html       |   93 -
 .../src/main/webapp/plugin/html/qdrOverview.html   |  210 --
 .../src/main/webapp/plugin/html/qdrSchema.html     |   21 -
 .../src/main/webapp/plugin/html/qdrTopology.html   |   67 -
 .../src/main/webapp/plugin/html/tmplListChart.html |   31 -
 .../src/main/webapp/plugin/html/tmplListTree.html  |   40 -
 .../main/webapp/plugin/html/tmplOverviewTree.html  |   35 -
 .../src/main/webapp/plugin/js/dispatchPlugin.js    |  297 --
 console/hawtio/src/main/webapp/plugin/js/navbar.js |  301 --
 .../src/main/webapp/plugin/js/qdrChartService.js   | 1154 --------
 .../hawtio/src/main/webapp/plugin/js/qdrCharts.js  |  331 ---
 .../hawtio/src/main/webapp/plugin/js/qdrList.js    |  804 ------
 .../src/main/webapp/plugin/js/qdrListChart.js      |  141 -
 .../src/main/webapp/plugin/js/qdrOverview.js       | 1686 ------------
 .../webapp/plugin/js/qdrOverviewLogsController.js  |   68 -
 .../hawtio/src/main/webapp/plugin/js/qdrSchema.js  |   81 -
 .../hawtio/src/main/webapp/plugin/js/qdrService.js | 1238 ---------
 .../src/main/webapp/plugin/js/qdrSettings.js       |  196 --
 .../src/main/webapp/plugin/js/qdrTopology.js       | 1960 -------------
 .../hawtio/src/main/webapp/plugin/lib/d3.min.js    |    6 -
 .../src/main/webapp/plugin/lib/jquery.tipsy.js     |  258 --
 .../hawtio/src/main/webapp/plugin/lib/rhea-min.js  |    6 -
 .../src/main/webapp/plugin/lib/tooltipsy.min.js    |   20 -
 .../src/main/webapp/plugin/lib/zd3-queue.min.js    |    2 -
 console/react/yarn.lock                            | 2902 ++++++++++++++------
 46 files changed, 2068 insertions(+), 13250 deletions(-)

diff --git a/LICENSE b/LICENSE
index c620013..261eeb9 100644
--- a/LICENSE
+++ b/LICENSE
@@ -199,28 +199,3 @@
    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.
-
-
-###############################################
-# Third Party Dependency Licensing Information:
-###############################################
-
-console/hawtio/src/main/webapp/plugin/lib/rhea-min.js is licensed under the above Apache License, Version 2.0
-
-The following 3 files are licensed under the BSD license, for details see licenses/d3.js-license
-1. console/dispatch-dashboard/dispatch/static/dashboard/dispatch/lib/d3.v3.min.js
-2. console/hawtio/src/main/webapp/plugin/lib/d3.min.js
-3. console/hawtio/src/main/webapp/plugin/lib/zd3-queue.min.js
-
-The following 2 files are covered by the MIT license, for details see licenses/jquery.tipsy-license
-1. console/hawtio/src/main/webapp/plugin/css/jquery.tipsy.css
-2. console/hawtio/src/main/webapp/plugin/lib/jquery.tipsy.js
-
-console/hawtio/src/main/webapp/plugin/css/jquery-ui.css is covered by the MIT License, for details see licenses/jquery-ui-license
-console/hawtio/src/main/webapp/plugin/lib/tooltipsy.min.js is licensed under the MIT license, for details see licenses/tooltipsy-license
-
-The following 3 files are covered by the SIL OFL 1.1, for details see licenses/fontawesome-license
-1. console/hawtio/src/main/webapp/plugin/fonts/fontawesome-webfont.woff
-2. console/hawtio/src/main/webapp/plugin/fonts/fontawesome-webfont.woff2
-3. console/hawtio/src/main/webapp/plugin/css/font-awesome.min.css
-
diff --git a/console/CMakeLists.txt b/console/CMakeLists.txt
index 46bb249..acd460d 100644
--- a/console/CMakeLists.txt
+++ b/console/CMakeLists.txt
@@ -99,26 +99,3 @@ if(CONSOLE_INSTALL)
   endif(NPM_EXECUTABLE)
 
 endif(CONSOLE_INSTALL)
-
-##
-## Add a custom make hawtio target
-##
-find_program (MAVEN_EXE mvn DOC "Location of the maven program")
-if (MAVEN_EXE)
-       # the directory where the .war file will be built
-       set(HAWTIO_BUILD_DIR "${CMAKE_BINARY_DIR}/hawtio")
-
-       # create the console .war file
-       add_custom_target(hawtio
-           COMMAND ${MAVEN_EXE} -DbuildDirectory=${HAWTIO_BUILD_DIR} package
-           WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/console/hawtio
-       )
-
-       # install the built war file into the console dir
-       install(
-           # We don't know in advance what the name of the final .war will be because
-           # the war file name depends on the version in the pom.xml. The version will change each release
-           CODE "file( GLOB builtwar \"${HAWTIO_BUILD_DIR}/dispatch-hawtio-console*.war\" )"
-           CODE "file( INSTALL \${builtwar} DESTINATION \"${CONSOLE_INSTALL_DIR}/hawtio\" )"
-       )
-endif(MAVEN_EXE)
diff --git a/console/hawtio/README.md b/console/hawtio/README.md
deleted file mode 100644
index 4cf332a..0000000
--- a/console/hawtio/README.md
+++ /dev/null
@@ -1,86 +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
--->
-
-# hawtio dispatch router plugin
-
-dispatch-hawtio-console.war is a standalone [hawtio](http://hawt.io/) plugin that can be deployed in a server alongside the main hawtio-web application.
-
-The project creates a war file that can be deployed in various application services and is also OSGi-ified so it deploys nicely into Apache Karaf.
-
-## Docker
-
-The fastest way to use the console is to run the [docker image](https://hub.docker.com/r/ernieallen/dispatch-console/). Follow the installation/run instruction on that page.
-
-## Building
-The dispatch-hawtio-console.war file is pre-built and can be installed alongside the hawtio.war on any system with a modern java installation. If you want to build the dispatch-hawtio-console.war from source:
-
-- do a maven build of dispatch
-
-    $ cd console/hawtio
-
-    $ mvn clean install
-
-The dispatch-hawtio-console-<version>-SNAPSHOT.war file should now be in the target directory.
-
-## Apache Tomcat installation
-
-Copy the dispatch-hawtio-console-<version>-SNAPSHOT.war file as the following name
-
-    dispatch-hawtio-console.war
-    
-to the deploy directory of Apache Tomcat or similar Java web container. Ensure the hawtio.war file is present in the same directory. Point a browser at http://\<tomcat-host:port\>/hawtio
-Dispatch Router should be available as a tab in the console.
-
-## Connecting to a router
-
-On the Dispatch Router's console page, select the Connect sub tab. Enter the address of a dispatch router. Enter the port of a websockets to tcp proxy and click the Connect button.
-
-### Websockets to tcp proxy
-
-The console communicates to a router using websockets. 
-The router listens for tcp. Therefore a websockets/tcp proxy is required.
-
-A popular python based proxy is [websockify](https://github.com/kanaka/websockify). To use it:
-
-    $ yum install python-websockify
-
-#### Manually running a python websockets/tcp proxy
-
-    $ websockify 5673 0.0.0.0:20009 &
-    
-In the above, websockify is listening for ws traffic on port 5673 and will proxy it to 0.0.0.0:20009. One of the routers will need a listener on the proxied port. An example router .conf file entry is:
-
-    listener {
-        name: ProxyListener
-        role: normal
-        host: 0.0.0.0
-        port: 20009
-        saslMechanisms: ANONYMOUS
-    }
-
-#### Automatically running a proxy with a router
-
-You can automatically start the proxy program when a router starts. Add the listener above and the following console section to a router's config file.
-
-    console {
-        listener: ProxyListener
-        proxy:    wobsockify
-        args:     $host:5673 $host:$port
-    }
-    
diff --git a/console/hawtio/pom.xml b/console/hawtio/pom.xml
deleted file mode 100644
index 6477aae..0000000
--- a/console/hawtio/pom.xml
+++ /dev/null
@@ -1,314 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
-  <parent>
-    <groupId>org.apache</groupId>
-    <artifactId>apache</artifactId>
-    <version>17</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <groupId>org.apache.qpid</groupId>
-  <artifactId>dispatch-hawtio-console</artifactId>
-  <version>1.11.0-SNAPSHOT</version>
-  <packaging>war</packaging>
-  <inceptionYear>2018</inceptionYear>
-  <url>https://qpid.apache.org</url>
-
-  <description>
-    Qpid Dispatch hawtio console plugin
-  </description>
-
-  <issueManagement>
-    <url>https://issues.apache.org/jira/browse/DISPATCH</url>
-    <system>JIRA</system>
-  </issueManagement>
-
-  <scm>
-    <connection>scm:git:http://gitbox.apache.org/repos/asf/qpid-dispatch.git</connection>
-    <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/qpid-dispatch.git</developerConnection>
-    <url>https://gitbox.apache.org/repos/asf?p=qpid-dispatch.git</url>
-  </scm>
-
-  <prerequisites>
-    <maven>3.0.4</maven>
-  </prerequisites>
-
-  <properties>
-    <!-- filtered plugin properties, we don't define plugin-scripts here
-      as we build that dynamically using maven-antrun-plugin below. -->
-    <!-- plugin-context is what context this plugin will handle requests on
-      in the application server -->
-    <plugin-context>/${project.artifactId}</plugin-context>
-
-    <!-- plugin-name is the name of our plugin, affects the name used for
-      the plugin's mbean -->
-    <plugin-name>${project.artifactId}</plugin-name>
-
-    <!-- plugin-domain is currently unused, we just define it to an empty
-      string -->
-    <plugin-domain />
-
-    <!-- dependency versions -->
-    <hawtio-version>1.4.60</hawtio-version>
-    <geronimo-servlet-2-5-spec-version>1.2</geronimo-servlet-2-5-spec-version>
-    <slf4j-version>1.7.13</slf4j-version>
-
-    <!-- plugin versions -->
-    <maven-antrun-plugin-version>1.7</maven-antrun-plugin-version>
-    <maven-bundle-plugin-version>2.3.7</maven-bundle-plugin-version>
-
-    <buildDirectory>${project.basedir}/target</buildDirectory>
-    <webapp-dir>${project.artifactId}-${project.version}</webapp-dir>
-    <webapp-outdir>${buildDirectory}/${webapp-dir}</webapp-outdir>
-
-    <!-- this lets this plugin deploy nicely into karaf, these get used
-      for the ImportPackage directive for maven-bundle-plugin -->
-    <dispatch.osgi.import>
-      javax.servlet,
-      *;resolution:=optional
-    </dispatch.osgi.import>
-
-    <maven.compiler.source>1.7</maven.compiler.source>
-    <maven.compiler.target>1.7</maven.compiler.target>
-  </properties>
-
-  <dependencies>
-
-    <!-- we only need to embed this dependency in the war, this contains
-      a nice helper class that our plugin can use to export it's plugin
-      mbean -->
-    <dependency>
-      <groupId>io.hawt</groupId>
-      <artifactId>hawtio-plugin-mbean</artifactId>
-      <version>${hawtio-version}</version>
-    </dependency>
-
-    <!-- logging -->
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-      <version>${slf4j-version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
-      <version>${slf4j-version}</version>
-    </dependency>
-
-    <!-- servlet API is provided by the container -->
-    <dependency>
-      <groupId>org.apache.geronimo.specs</groupId>
-      <artifactId>geronimo-servlet_2.5_spec</artifactId>
-      <version>${geronimo-servlet-2-5-spec-version}</version>
-      <scope>provided</scope>
-    </dependency>
-
-  </dependencies>
-
-  <build>
-
-    <directory>${buildDirectory}</directory>
-    <!-- we want to ensure src/main/resources/WEB-INF/web.xml is being filtered
-      so that it picks up all of our javascript files -->
-    <resources>
-      <resource>
-        <directory>src/main/resources</directory>
-        <filtering>true</filtering>
-        <includes>
-          <include>**/*.xml</include>
-        </includes>
-      </resource>
-    </resources>
-
-    <plugins>
-
-      <!-- We use maven-antrun-plugin to build up a list of
-           javascript files for our plugin mbean, this means
-           it needs to run before the maven-resources-plugin
-           copies and filters the web.xml, since for this
-           example we use contextParam settings to configure
-           our plugin mbean -->
-
-      <plugin>
-        <artifactId>maven-antrun-plugin</artifactId>
-        <version>${maven-antrun-plugin-version}</version>
-        <executions>
-
-          <execution>
-            <!-- we run this early in the build process before
-              maven-resources-plugin is run.  We're exporting the
-              plugin-scripts property from here, so we need to
-              use maven-antrun-plugin 1.6 or up -->
-            <id>generate-sources</id>
-            <phase>generate-sources</phase>
-            <goals>
-              <goal>run</goal>
-            </goals>
-            <configuration>
-              <target>
-                <echo>Building plugin javascript file list</echo>
-                <!-- javascript-files will contain all of the javascript in
-                  our project -->
-                <fileset id="javascript-files" dir="${basedir}/src/main/webapp">
-                  <include name="**/*.js" />
-                </fileset>
-                <!-- we need to strip out the top level path which is
-                   our source directory and be sure to change the directory
-                   separators to forward slashes -->
-                <pathconvert pathsep="," dirsep="/" property="plugin-scripts" refid="javascript-files">
-                  <map from="${basedir}/src/main/webapp/" to="" />
-                </pathconvert>
-                <echo>Files: ${plugin-scripts}</echo>
-
-                <echo>Copying log4j.properties</echo>
-                <copy file="src/main/resources/log4j.properties" todir="${buildDirectory}/classes" />
-
-              </target>
-              <!-- this exports plugin-scripts to the maven build, without
-                this line ${plugin-scripts} in the web.xml file won't be
-                replaced -->
-              <exportAntProperties>true</exportAntProperties>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-
-      <plugin>
-        <artifactId>maven-resources-plugin</artifactId>
-        <executions>
-          <execution>
-            <!-- defining this maven plugin in the same phase as the
-              maven-antrun-plugin but *after* we've configured the
-              maven-antrun-plugin ensures we filter resources *after*
-              we've discovered the plugin .js files. -->
-            <id>copy-resources</id>
-            <phase>generate-sources</phase>
-            <goals>
-              <goal>resources</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-
-      <!-- maven-bundle-plugin config, needed to make this war
-        deployable in karaf, defines the context that this bundle
-        should handle requests on -->
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <version>${maven-bundle-plugin-version}</version>
-        <executions>
-          <execution>
-            <id>bundle-manifest</id>
-            <phase>process-classes</phase>
-            <goals>
-              <goal>manifest</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <manifestLocation>${webapp-outdir}/META-INF</manifestLocation>
-          <supportedProjectTypes>
-            <supportedProjectType>jar</supportedProjectType>
-            <supportedProjectType>bundle</supportedProjectType>
-            <supportedProjectType>war</supportedProjectType>
-          </supportedProjectTypes>
-          <instructions>
-            <Webapp-Context>${plugin-context}</Webapp-Context>
-            <Web-ContextPath>${plugin-context}</Web-ContextPath>
-
-            <Embed-Directory>WEB-INF/lib</Embed-Directory>
-            <Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
-            <Embed-Transitive>true</Embed-Transitive>
-
-            <Export-Package>${dispatch.osgi.export}</Export-Package>
-            <Import-Package>${dispatch.osgi.import}</Import-Package>
-            <DynamicImport-Package>${dispatch.osgi.dynamic}</DynamicImport-Package>
-            <Private-Package>${dispatch.osgi.private.pkg}</Private-Package>
-
-            <Bundle-ClassPath>.,WEB-INF/classes</Bundle-ClassPath>
-
-            <Bundle-Name>${project.description}</Bundle-Name>
-            <Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
-            <Implementation-Title>HawtIO</Implementation-Title>
-            <Implementation-Version>${project.version}</Implementation-Version>
-          </instructions>
-        </configuration>
-      </plugin>
-
-      <!-- We define the maven-war-plugin here and make sure it uses
-        the manifest file generated by the maven-bundle-plugin.  We
-        also ensure it picks up our filtered web.xml and not the one
-        in src/main/resources -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-war-plugin</artifactId>
-        <configuration>
-          <outputFileNameMapping>@{artifactId}@-@{baseVersion}@@{dashClassifier?}@.@{extension}@</outputFileNameMapping>
-          <packagingExcludes>**/classes/OSGI-INF/**</packagingExcludes>
-          <failOnMissingWebXml>false</failOnMissingWebXml>
-          <archive>
-            <manifestFile>${webapp-outdir}/META-INF/MANIFEST.MF</manifestFile>
-          </archive>
-          <webResources>
-            <resource>
-              <filtering>true</filtering>
-              <directory>src/main/resources</directory>
-              <includes>
-                <include>**/*.*</include>
-              </includes>
-            </resource>
-            <webResource>
-              <targetPath>META-INF</targetPath>
-              <directory>${basedir}/src/main/assembly/META-INF</directory>
-            </webResource>
-          </webResources>
-        </configuration>
-      </plugin>
-
-    </plugins>
-  </build>
-
-  <profiles>
-    <!-- Profile to override the parent pom profile of the same name to
-         stop creation of a source-release.zip file here, as the overall
-         dispatch source release was generated separately already. -->
-    <profile>
-      <id>apache-release</id>
-      <build>
-        <plugins>
-          <plugin>
-            <artifactId>maven-assembly-plugin</artifactId>
-            <executions>
-              <execution>
-                <id>source-release-assembly</id>
-                <phase>package</phase>
-                <goals>
-                  <goal>single</goal>
-                </goals>
-                <configuration>
-                  <skipAssembly>true</skipAssembly>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
-</project>
diff --git a/console/hawtio/src/main/assembly/META-INF/LICENSE b/console/hawtio/src/main/assembly/META-INF/LICENSE
deleted file mode 100644
index 1c79982..0000000
--- a/console/hawtio/src/main/assembly/META-INF/LICENSE
+++ /dev/null
@@ -1,234 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed 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.
-
-
-
-###############################################
-# Third Party Dependency Licensing Information:
-###############################################
-
-This product bundles SLF4J-API and SLF4J-LOG4J, which are distributed under
-the MIT licence:
-
-Copyright (c) 2004-2013 QOS.ch
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
diff --git a/console/hawtio/src/main/assembly/META-INF/NOTICE b/console/hawtio/src/main/assembly/META-INF/NOTICE
deleted file mode 100644
index dfa35dd..0000000
--- a/console/hawtio/src/main/assembly/META-INF/NOTICE
+++ /dev/null
@@ -1,6 +0,0 @@
-Qpid Dispatch hawtio console
-Copyright 2016 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
diff --git a/console/hawtio/src/main/java/org/apache/qpid/dispatch/PluginContextListener.java b/console/hawtio/src/main/java/org/apache/qpid/dispatch/PluginContextListener.java
deleted file mode 100644
index 806f7a0..0000000
--- a/console/hawtio/src/main/java/org/apache/qpid/dispatch/PluginContextListener.java
+++ /dev/null
@@ -1,57 +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.
- *
-*/
-package org.apache.qpid.dispatch;
-
-import io.hawt.web.plugin.HawtioPlugin;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.servlet.ServletContext;
-import javax.servlet.ServletContextEvent;
-import javax.servlet.ServletContextListener;
-
-public class PluginContextListener implements ServletContextListener {
-
-  private static final Logger LOG = LoggerFactory.getLogger(PluginContextListener.class);
-
-  HawtioPlugin plugin = null;
-
-  @Override
-  public void contextInitialized(ServletContextEvent servletContextEvent) {
-
-    ServletContext context = servletContextEvent.getServletContext();
-
-    plugin = new HawtioPlugin();
-    plugin.setContext((String)context.getInitParameter("plugin-context"));
-    plugin.setName(context.getInitParameter("plugin-name"));
-    plugin.setScripts(context.getInitParameter("plugin-scripts"));
-    plugin.setDomain(null);
-    plugin.init();
-
-    LOG.info("Initialized {} plugin", plugin.getName());
-  }
-
-  @Override
-  public void contextDestroyed(ServletContextEvent servletContextEvent) {
-    plugin.destroy();
-    LOG.info("Destroyed {} plugin", plugin.getName());
-  }
-}
diff --git a/console/hawtio/src/main/resources/WEB-INF/web.xml b/console/hawtio/src/main/resources/WEB-INF/web.xml
deleted file mode 100644
index ee81d02..0000000
--- a/console/hawtio/src/main/resources/WEB-INF/web.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.
--->
-<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
-	      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	      xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
-	      http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
-	      version="2.4">
-
-  <description>Qpid Dispatch Router console hawt.io plugin</description>
-  <display-name>Dispatch Router console</display-name>
-
-  <context-param>
-    <description>Plugin's path on the server</description>
-    <param-name>plugin-context</param-name>
-    <param-value>${plugin-context}</param-value>
-  </context-param>
-
-  <context-param>
-    <description>Plugin's path on the server</description>
-    <param-name>plugin-name</param-name>
-    <param-value>${project.artifactId}</param-value>
-  </context-param>
-
-  <context-param>
-    <description>Plugin's path on the server</description>
-    <param-name>plugin-domain</param-name>
-    <param-value>${plugin-domain}</param-value>
-  </context-param>
-
-  <context-param>
-    <description>Plugin's path on the server</description>
-    <param-name>plugin-scripts</param-name>
-    <param-value>${plugin-scripts}</param-value>
-  </context-param>
-
-  <listener>
-    <listener-class>org.apache.qpid.dispatch.PluginContextListener</listener-class>
-  </listener>
-
-
-</web-app>
-
diff --git a/console/hawtio/src/main/resources/log4j.properties b/console/hawtio/src/main/resources/log4j.properties
deleted file mode 100644
index e327212..0000000
--- a/console/hawtio/src/main/resources/log4j.properties
+++ /dev/null
@@ -1,25 +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.
-#
-log4j.rootLogger=INFO, console
-
-log4j.appender.console=org.apache.log4j.ConsoleAppender
-log4j.appender.console.layout=org.apache.log4j.PatternLayout
-log4j.appender.console.layout.ConversionPattern=%-5p | %t | %m%n
-
diff --git a/console/hawtio/src/main/webapp/index.html b/console/hawtio/src/main/webapp/index.html
deleted file mode 100644
index 12369fb..0000000
--- a/console/hawtio/src/main/webapp/index.html
+++ /dev/null
@@ -1,26 +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
--->
-
-<html>
-<body>
-    <h3>Welcome to Qpid Dispatch Router's hawtio console.</h3>
-
-    <p>For more info about this console, please see <a href="https://qpid.apache.org/releases/qpid-dispatch-0.6.0/book/console.html">The Apache Qpid Dispatch Router Book</a></p>
-</body>
-</html>
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/css/brokers.ttf b/console/hawtio/src/main/webapp/plugin/css/brokers.ttf
deleted file mode 100644
index ae83968..0000000
Binary files a/console/hawtio/src/main/webapp/plugin/css/brokers.ttf and /dev/null differ
diff --git a/console/hawtio/src/main/webapp/plugin/css/dispatch.css b/console/hawtio/src/main/webapp/plugin/css/dispatch.css
deleted file mode 100644
index 5c946bd..0000000
--- a/console/hawtio/src/main/webapp/plugin/css/dispatch.css
+++ /dev/null
@@ -1,726 +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.
-*/
-
-svg {
-  background-color: transparent;
-  cursor: default;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  -o-user-select: none;
-  user-select: none;
-}
-
-svg:not(.active):not(.ctrl) {
-  cursor: crosshair;
-}
-#end-arrow-selected, #start-arrow-selected {
-	stroke: #33F;
-	fill: #33F;
-}
-path.link.selected {
-  stroke-dasharray: 10,2;
-  stroke: #33F  !important;
-}
-
-path.link {
-  fill: #000;
-  stroke: #000;
-  stroke-width: 4px;
-  cursor: default;
-}
-
-svg:not(.active):not(.ctrl) path.link {
-  cursor: pointer;
-}
-
-path.link.small {
-  stroke-width: 2.5;
-  stroke: darkgray;
-}
-path.link.highlighted {
-    stroke: #6F6 !important;
-}
-marker#start-arrow-highlighted,
-marker#end-arrow-highlighted {
-    fill: #6F6;
-}
-marker#start-arrow-small,
-marker#end-arrow-small {
-    fill: darkgray;
-}
-
-path.link.dragline {
-  pointer-events: none;
-}
-
-path.link.hidden {
-  stroke-width: 0;
-}
-
-circle.node {
-  stroke-width: 1.5px;
-  cursor: pointer;
-  stroke: darkgray;
-}
-
-circle.node.reflexive {
-  stroke: #F00 !important;
-  stroke-width: 2.5px;
-}
-circle.node.selected {
-  stroke: #6F6 !important;
-  stroke-width: 2px;
-  fill: #e0e0ff !important;
-}
-circle.node.highlighted {
-  stroke: #6F6;
-}
-circle.node.inter-router {
-    fill: #EAEAEA;
-}
-circle.node.normal.in {
-    fill: #F0F000;
-}
-circle.node.normal.out {
-    fill: #C0F0C0;
-}
-circle.node.on-demand {
-    fill: #C0FFC0;
-}
-circle.node.on-demand.artemis {
-	fill: #FCC;
-	/*opacity: 0.2; */
-}
-
-circle.node.fixed {
-    stroke-dasharray: 10,2;
-}
-text {
-  font: 12px sans-serif;
-  pointer-events: none;
-  /*font-family: monospace;*/
-
-}
-
-.tooltipsy
-{
-    padding: 10px;
-/*    max-width: 320px;*/
-    color: #303030;
-    background-color: #fcfcfe;
-    border: 1px solid #deca7e;
-    border-radius: 5px;
-}
-
-.tiptable {
-
-}
-.tiptable tr {
-	border-bottom: 1px solid #ccc;
-}
-
-.tiptable tr:last-child {
-	border-bottom: 0px;
-}
-
-.tiptable tr:nth-child(even) {
-	background: #fcfcfe;
-}
-.tiptable tr:nth-child(odd) {
-	background: #FFF
-}
-
-text.id {
-  text-anchor: middle;
-  font-weight: bold;
-}
-
-text.label {
-  text-anchor: start;
-  font-weight: bold;
-}
-
-.row-fluid.tertiary {
-  position: relative;
-  left: 20px;
-}
-
-.row-fluid.tertiary.left {
-  float: left;
-}
-
-.row-fluid.tertiary.panel {
-  width: 410px;
-  /*height: 100%; */
-}
-
-div#topologyForm .ngViewport, div#topologyForm .gridStyle {
-  height: auto !important;
-  min-height: initial !important;
-  overflow: initial;
-}
-
-div#multiple_details, div#link_details {
-	height: 300px;
-	width: 700px;
-	display: none;
-	padding: 0.5em;
-    border: 1px solid;
-	position: absolute;
-	background-color: white;
-	max-height: 330px !important;
-    overflow: hidden;
-}
-div#multiple_details div.ngRow.selected {
-	background-color: #c9dde1 !important;
-}
-
-div.grid-values {
-	text-align: right;
-}
-
-div.grid-values.ngCellText span {
-	padding-right: 4px;
-}
-
-.panel-adjacent {
-  margin-left: 430px;
-}
-
-#topologyForm.selected {
-  border: 1px solid blue;
-}
-#topologyForm {
-  border-right: 1px solid lightgray;
-  border-bottom: 1px solid lightgray;
-    /*border: 1px solid white;*/
-    padding: 2px;
-    /* position: relative; */
-    /* top: -8px; */
-}
-div.qdr-topology.pane.left .ngViewport {
-    /* border: 1px solid lightgray; */
-}
-
-#topologyForm > div {
-  width:396px;
-}
-
-/* globe */
-.land {
-  fill: #999;
-  stroke-opacity: 1;
-}
-
-.graticule {
-  fill: none;
-  stroke: black;
-  stroke-width:.5;
-  opacity:.1;
-}
-
-.labels {
-    font: 18px sans-serif;
-    fill: black;
-    opacity: .85;
-	text-anchor: middle;
-}
-
-.noclicks { pointer-events:none; }
-
-.point {  opacity:.6; }
-
-.arcs {
-  opacity:.7;
-  stroke: darkgreen;
-  stroke-width: 3;
-}
-.flyers {
-  stroke-width:1;
-  opacity: 0;
-  stroke: darkred;
-}
-.arc, .flyer {
-  stroke-linejoin: round;
-  fill:none;
-}
-.arc { }
-.arc:hover {
-  stroke: darkred;
-}
-.flyer { }
-.flyer:hover {
-  stroke: darkgreen;
-}
-.arc.inter-router {
-  stroke: darkblue;
-}
-
-#addNodeForm {
-  padding: 1em;
-}
-
-
-li.currentStep {
-  font-weight: bold;
-}
-
-.qdrTopology div.panel {
-  position: absolute;
-}
-/*
-.ui-dialog-titlebar {
-    border: 0;
-    background: transparent;
-}
-*/
-
-/*
-.ui-tabs.ui-tabs-vertical {
-    padding: 0;
-    width: 48em;
-}
-.ui-tabs.ui-tabs-vertical .ui-widget-header {
-    border: none;
-}
-.ui-tabs.ui-tabs-vertical .ui-tabs-nav {
-    float: left;
-    width: 10em;
-    background: #CCC;
-    border-radius: 4px 0 0 4px;
-    border-right: 1px solid gray;
-}
-.ui-tabs.ui-tabs-vertical .ui-tabs-nav li {
-    clear: left;
-    width: 100%;
-    margin: 0.1em 0;
-    border: 1px solid gray;
-    border-width: 1px 0 1px 1px;
-    border-radius: 4px 0 0 4px;
-    overflow: hidden;
-    position: relative;
-    right: -2px;
-    z-index: 2;
-}
-.ui-tabs.ui-tabs-vertical .ui-tabs-nav li a {
-    display: block;
-    width: 100%;
-    padding: 0.1em 1em;
-}
-.ui-tabs.ui-tabs-vertical .ui-tabs-nav li a:hover {
-    cursor: pointer;
-}
-.ui-tabs.ui-tabs-vertical .ui-tabs-nav li.ui-tabs-active {
-    margin-bottom: 0.2em;
-    padding-bottom: 0;
-    border-right: 1px solid white;
-}
-.ui-tabs.ui-tabs-vertical .ui-tabs-nav li:last-child {
-    margin-bottom: 10px;
-}
-.ui-tabs.ui-tabs-vertical .ui-tabs-panel {
-    float: left;
-    width: 34em;
-    border-left: 1px solid gray;
-    border-radius: 0;
-    position: relative;
-    left: -1px;
-}
-
-.ui-tabs .ui-tabs-nav li.ui-tabs-selected {
-    right: -3px !important;
-}
-
-.ui-tabs li i.ui-icon {
-    display: inline-block;
-}
-*/
-.ui-tabs .ui-tabs-panel {
-    /* padding-top: 0 !important; */
-}
-
-.ui-widget-content fieldset {
-  float: left;
-  padding: 0 1em 0 0;
-}
-
-.entity-description {
-  color: #960;
-  font-size: 90%;
-}
-
-.attr-description {
-  padding-top: 1.5em;
-  float: right;
-  width: 17em;
-}
-.attr-annotations {
-    padding-top: 2.5em;
-    clear: both;
-}
-.attr-annotations > span {
-    padding-top: 0.5em;
-    border-top: 1px dashed darkgray;
-    display: block;
-}
-
-.attr-type {
-    color: #990;
-    font-size: 85%;
-}
-.attr-required {
-    color: red;
-    font-size: 85%;
-}
-.attr-unique {
-    color: green;
-    font-size: 85%;
-}
-
-#tabs.nodeEntities {
-  border: 0;
-}
-
-#tabs ul.nodeTabs {
-  background: #fff;
-}
-
-#tabs #Container {
-  border-left: 1px solid #aaa;
-}
-
-#tabs.ui-tabs .ui-tabs-nav li {
-  border-bottom: 1px solid #aaa !important;
-}
-
-.entity-fields {
-  /* height: 400px; */
-  overflow-y: scroll;
-  overflow-x: hidden;
-}
-
-div.boolean label:first-child {
-    float: left;
-    margin-right: 1em;
-}
-div.boolean {
-    padding-bottom: 1em;
-}
-
-.entity-fields label {
-    font-weight: 600;
-    margin-top: 0.5em;
-	display: inline;
-}
-
-.aggregate {
-	text-align: right;
-}
-
-.aggregate i {
-	float: right;
-    margin: 3px 3px 3px 8px;
-}
-
-.aggregate .hastip {
-	padding: 5px;
-}
-
-.subTip .tipsy-inner {
-	background-color: white;
-	color: black;
-	font-size: 1.3em;
-	border: 1px solid black;
-}
-
-.subTip .tipsy-arrow-n { border-bottom-color: black; }
-.subTip .tipsy-arrow-s { border-top-color: black; }
-.subTip .tipsy-arrow-e { border-left-color: black; }
-.subTip .tipsy-arrow-w { border-right-color: black; }
-
-
-.contextMenu {
-    display:none;
-	position:absolute;
-	left:30px;
-	top:-30px;
-	z-index:999;
-	/* width:300px; */
-}
-.contextMenu ul {
-	width:300px;
-	margin:0;
-	padding-left:0;
-	list-style:none;
-	background:#fff;
-	color:#333;
-    font-weight: 600;
-	/* -moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px; */
-	-moz-box-shadow:5px 5px 5px #ddd; -webkit-box-shadow:5px 5px 5px #999; box-shadow:5px 5px 5px #ddd;
-	border: 1px solid #aaa;
-}
-.contextMenu ul li {
-	padding:5px 10px;
-	/* border-bottom: solid 1px #ccc; */
-}
-.contextMenu ul li:hover {
-	background:#4a90d9; color:#fff;
-}
-.contextMenu ul li:last-child {
-    border:none;
-}
-
-.na {
-    display: none;
-}
-.contextMenu ul li.new {
-    display: block;
-}
-.contextMenu ul li.adding, .contextMenu ul li.adding + li {
-    display: block;
-}
-.contextMenu ul li.force-display {
-    display: block;
-}
-.contextMenu ul li.context-separator {
-    background-color: lightgray;
-    height: 1px;
-    padding: 0;
-}
-
-.ui-tabs.ui-tabs-vertical .ui-tabs-nav li.separated {
-    margin-top: 1em;
-}
-
-#crosssection {
-    display: none;
-    position: absolute;
-    top: 200px;
-    left: 600px;
-}
-
-.node circle {
-/*  fill: rgb(31, 119, 180);
-  fill-opacity: .25; */
-  fill: #cfe2f3;
-  fill-opacity: .98;
-  stroke: black;
-  stroke-width: 3px;
-}
-
-circle.subcircle {
-    stroke-width: 1px;
-    /* stroke-dasharray: 2; */
-    fill-opacity: 0;
-    stroke: darkgray;
-}
-
-.leaf circle {
-  fill: #6fa8dc;
-  fill-opacity: 0.95;
-  stroke-width: 3px;
-}
-
-.leaf circle[title] {
-    font-family: monospace;
-
-}
-
-#svg_legend {
-    position: absolute;
-    top: 110px;
-    right: 0;
-    border: 1px solid #ccc;
-    border-radius: 5px;
-    background-color: #fcfcfc;
-    margin-right: 1.3em;
-	padding: 1em;
-}
-
-#svg_legend svg {
-    height: 235px;
-    width: 180px;
-}
-
-#multiple_details div.gridStyle {
-/*	height: 50em; */
-	min-height: 70px !important;
-	height: auto !important;
-}
-
-#multiple_details .ngViewport {
-    height: auto !important;
-}
-
-#multiple_details .gridCellButton button, #link_details .gridCellButton button {
-    margin: .25em .4em;
-    font-size: 12px;
-    height: 2em;
-	padding-top: .1em;
-}
-
-#linkFilter {
-	display: none;
-	padding: 0.5em;
-	border: 1px solid grey;
-	background-color: #F0F0F0;
-	position: absolute;
-	z-index: 100;
-	right: 1em;
-}
-div.formLine label, div.formLine input {
-	display: inline-block;
-	padding: 0 8px;
-}
-
-span.filter-icon {
-	padding-left: 1em;
-}
-
-button.filter-close {
-    width: 15px;
-    height: 20px;
-    padding: 0;
-    position: absolute;
-    right: 4px;
-    top: 4px;
-}
-
-div.filter-title h6 {
-	margin: 0 0 0.5em 0;
-}
-
-.links button.btn-filter {
-	padding: 0 1em 0 0;
-    margin-left: 1em;
-    font-size: 1em;
-}
-
-button.btn-filter {
-	float: right;
-}
-span.dynatree-expanded button.btn-filter,
-a.dynatree-title:hover button.btn-filter {
- 	visibility: visible;
-}
-
-div.hdash-button a {
-	color: white;
-}
-
-.linkDirIn {
-	color: red;
-	background-color: #f3f3f3;
-}
-
-.linkDirOut {
-	color: blue;
-	background-color: white;
-}
-
-div.topoGrid .ui-grid-viewport {
-	overflow: hidden !important;
-}
-
-@-moz-document url-prefix() {
-    .btn {padding: 2px 12px 8px !important;}
-    #overview-controller .btn {padding: 4px 12px !important;}
-    #overview-controller .btn.filter-close {padding: 0 !important;}
-}
-
-.ui-fancytree.fancytree-container {
-	font-size: 14px;
-}
-
-.grid-title {
-    background-color: #FAFAFA;
-    background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2);
-    background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2));
-    background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2);
-    background-image: -o-linear-gradient(top, #ffffff, #f2f2f2);
-    background-image: linear-gradient(to bottom, #ffffff, #f2f2f2);
-    background-repeat: repeat-x;
-    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFF', endColorstr='#F2F2F2', GradientType=0);
-    border-bottom: 1px solid #d4d4d4;
-    text-shadow: 0 1px 0 #FFFFFF;
-    border-top-left-radius: 5px;
-    border-top-right-radius: 5px;
-	margin: 0 0 10px 0;
-    padding-bottom: 4px;
-}
-
-.expand-collapse {
-	float: right;
-	margin-right: 0.5em;
-}
-
-.pane-viewport {
-	top: 24px !important;
-}
-.dynatree-node.loading {
-  position: initial;
-}
-
-.hideLeft {
-  position: absolute;
-  right: 0.5em;
-  top: 1em;
-  border: 0;
-}
-
-.showLeft {
-  position: absolute;
-  top: 1em;
-  left: 0.5em;
-  border: 0;
-}
-
-.newChart {
-  float: right;
-}
-
-select.unique, input.unique {
-  border: 2px solid blue;
-}
-select.required, input.required {
-  border: 2px solid black;
-}
-
-.required-indicator {
-  padding-left: 0.5em;
-  font-size: 0.85em;
-  vertical-align: super;
-}
-
-.required-indicator::before {
-  content: '(required)'
-}
-
-.unique-indicator {
-  padding-left: 0.5em;
-  font-size: 0.85em;
-  vertical-align: super;
-}
-
-.unique-indicator::before {
-  content: '(must be unique if supplied)'
-}
-
-.unique-indicator
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/css/font-awesome.min.css b/console/hawtio/src/main/webapp/plugin/css/font-awesome.min.css
deleted file mode 100644
index d0603cb..0000000
--- a/console/hawtio/src/main/webapp/plugin/css/font-awesome.min.css
+++ /dev/null
@@ -1,4 +0,0 @@
-/*!
- *  Font Awesome 4.5.0 by @davegandy - http://fontawesome.io - @fontawesome
- *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
- */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.5.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.5.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.5.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.5.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.5.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.5.0#fontawesomeregular') format('svg');font-weight:normal;font-style:norma [...]
diff --git a/console/hawtio/src/main/webapp/plugin/css/jquery-ui.css b/console/hawtio/src/main/webapp/plugin/css/jquery-ui.css
deleted file mode 100644
index e0625dc..0000000
--- a/console/hawtio/src/main/webapp/plugin/css/jquery-ui.css
+++ /dev/null
@@ -1,464 +0,0 @@
-/*! jQuery UI - v1.8.24 - 2012-09-28
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.core.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.progressbar.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.slider.css, jquery.ui.tabs.css, jquery.ui.theme.css
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-
-/* Layout helpers
-----------------------------------*/
-.ui-helper-hidden { display: none; }
-.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
-.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
-.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; }
-.ui-helper-clearfix:after { clear: both; }
-.ui-helper-clearfix { zoom: 1; }
-.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
-
-
-/* Interaction Cues
-----------------------------------*/
-.ui-state-disabled { cursor: default !important; }
-
-
-/* Icons
-----------------------------------*/
-
-/* states and images */
-.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
-
-
-/* Misc visuals
-----------------------------------*/
-
-/* Overlays */
-.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
-
-/* IE/Win - Fix animation bug - #4615 */
-.ui-accordion { width: 100%; }
-.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
-.ui-accordion .ui-accordion-li-fix { display: inline; }
-.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
-.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
-.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
-.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
-.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
-.ui-accordion .ui-accordion-content-active { display: block; }
-
-.ui-autocomplete { position: absolute; cursor: default; }	
-
-/* workarounds */
-* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
-
-/*
- * jQuery UI Menu 1.8.24
- *
- * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Menu#theming
- */
-.ui-menu {
-	list-style:none;
-	padding: 2px;
-	margin: 0;
-	display:block;
-	float: left;
-}
-.ui-menu .ui-menu {
-	margin-top: -3px;
-}
-.ui-menu .ui-menu-item {
-	margin:0;
-	padding: 0;
-	zoom: 1;
-	float: left;
-	clear: left;
-	width: 100%;
-}
-.ui-menu .ui-menu-item a {
-	text-decoration:none;
-	display:block;
-	padding:.2em .4em;
-	line-height:1.5;
-	zoom:1;
-}
-.ui-menu .ui-menu-item a.ui-state-hover,
-.ui-menu .ui-menu-item a.ui-state-active {
-	font-weight: normal;
-	margin: -1px;
-}
-
-.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
-.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
-button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
-.ui-button-icons-only { width: 3.4em; } 
-button.ui-button-icons-only { width: 3.7em; } 
-
-/*button text element */
-.ui-button .ui-button-text { display: block; line-height: 1.4;  }
-.ui-button-text-only .ui-button-text { padding: .4em 1em; }
-.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
-.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
-.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
-.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
-/* no icon support for input elements, provide padding by default */
-input.ui-button { padding: .4em 1em; }
-
-/*button icon element(s) */
-.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
-.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
-.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
-.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
-.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
-
-/*button sets*/
-.ui-buttonset { margin-right: 7px; }
-.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
-
-/* workarounds */
-button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
-
-.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
-.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
-.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
-.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
-.ui-datepicker .ui-datepicker-prev { left:2px; }
-.ui-datepicker .ui-datepicker-next { right:2px; }
-.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
-.ui-datepicker .ui-datepicker-next-hover { right:1px; }
-.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px;  }
-.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
-.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
-.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
-.ui-datepicker select.ui-datepicker-month, 
-.ui-datepicker select.ui-datepicker-year { width: 49%;}
-.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
-.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0;  }
-.ui-datepicker td { border: 0; padding: 1px; }
-.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
-.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
-.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
-.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
-
-/* with multiple calendars */
-.ui-datepicker.ui-datepicker-multi { width:auto; }
-.ui-datepicker-multi .ui-datepicker-group { float:left; }
-.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
-.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
-.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
-.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
-.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
-.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
-.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
-.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; }
-
-/* RTL support */
-.ui-datepicker-rtl { direction: rtl; }
-.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
-.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
-.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
-.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
-.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
-.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
-.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
-.ui-datepicker-rtl .ui-datepicker-group { float:right; }
-.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
-.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
-
-/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
-.ui-datepicker-cover {
-    position: absolute; /*must have*/
-    z-index: -1; /*must have*/
-    filter: mask(); /*must have*/
-    top: -4px; /*must have*/
-    left: -4px; /*must have*/
-    width: 200px; /*must have*/
-    height: 200px; /*must have*/
-}
-.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
-.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative;  }
-.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } 
-.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
-.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
-.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
-.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
-.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
-.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
-.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
-.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
-.ui-draggable .ui-dialog-titlebar { cursor: move; }
-
-.ui-progressbar { height:2em; text-align: left; overflow: hidden; }
-.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
-.ui-resizable { position: relative;}
-.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; }
-.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
-.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
-.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
-.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
-.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
-.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
-.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
-.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
-.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}
-.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
-
-.ui-slider { position: relative; text-align: left; }
-.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
-.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
-
-.ui-slider-horizontal { height: .8em; }
-.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
-.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
-.ui-slider-horizontal .ui-slider-range-min { left: 0; }
-.ui-slider-horizontal .ui-slider-range-max { right: 0; }
-
-.ui-slider-vertical { width: .8em; height: 100px; }
-.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
-.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
-.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
-.ui-slider-vertical .ui-slider-range-max { top: 0; }
-.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
-.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
-.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
-.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
-.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
-.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
-.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
-.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
-.ui-tabs .ui-tabs-hide { display: none !important; }
-
-/* Component containers
-----------------------------------*/
-.ui-widget { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1.1em/*{fsDefault}*/; }
-.ui-widget .ui-widget { font-size: 1em; }
-.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1em; }
-.ui-widget-content { border: 1px solid #aaaaaa/*{borderColorContent}*/; background: #ffffff/*{bgColorContent}*/ url(images/ui-bg_flat_75_ffffff_40x100.png)/*{bgImgUrlContent}*/ 50%/*{bgContentXPos}*/ 50%/*{bgContentYPos}*/ repeat-x/*{bgContentRepeat}*/; color: #222222/*{fcContent}*/; }
-.ui-widget-content a { color: #222222/*{fcContent}*/; }
-.ui-widget-header { border: 1px solid #aaaaaa/*{borderColorHeader}*/; background: #cccccc/*{bgColorHeader}*/ url(images/ui-bg_highlight-soft_75_cccccc_1x100.png)/*{bgImgUrlHeader}*/ 50%/*{bgHeaderXPos}*/ 50%/*{bgHeaderYPos}*/ repeat-x/*{bgHeaderRepeat}*/; color: #222222/*{fcHeader}*/; font-weight: bold; }
-.ui-widget-header a { color: #222222/*{fcHeader}*/; }
-
-/* Interaction states
-----------------------------------*/
-.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3/*{borderColorDefault}*/; background: #e6e6e6/*{bgColorDefault}*/ url(images/ui-bg_glass_75_e6e6e6_1x400.png)/*{bgImgUrlDefault}*/ 50%/*{bgDefaultXPos}*/ 50%/*{bgDefaultYPos}*/ repeat-x/*{bgDefaultRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #555555/*{fcDefault}*/; }
-.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555/*{fcDefault}*/; text-decoration: none; }
-.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999/*{borderColorHover}*/; background: #dadada/*{bgColorHover}*/ url(images/ui-bg_glass_75_dadada_1x400.png)/*{bgImgUrlHover}*/ 50%/*{bgHoverXPos}*/ 50%/*{bgHoverYPos}*/ repeat-x/*{bgHoverRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcHover}*/; }
-.ui-state-hover a, .ui-state-hover a:hover { color: #212121/*{fcHover}*/; text-decoration: none; }
-.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa/*{borderColorActive}*/; background: #ffffff/*{bgColorActive}*/ url(images/ui-bg_glass_65_ffffff_1x400.png)/*{bgImgUrlActive}*/ 50%/*{bgActiveXPos}*/ 50%/*{bgActiveYPos}*/ repeat-x/*{bgActiveRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcActive}*/; }
-.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121/*{fcActive}*/; text-decoration: none; }
-.ui-widget :active { outline: none; }
-
-/* Interaction Cues
-----------------------------------*/
-.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight  {border: 1px solid #fcefa1/*{borderColorHighlight}*/; background: #fbf9ee/*{bgColorHighlight}*/ url(images/ui-bg_glass_55_fbf9ee_1x400.png)/*{bgImgUrlHighlight}*/ 50%/*{bgHighlightXPos}*/ 50%/*{bgHighlightYPos}*/ repeat-x/*{bgHighlightRepeat}*/; color: #363636/*{fcHighlight}*/; }
-.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636/*{fcHighlight}*/; }
-.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a/*{borderColorError}*/; background: #fef1ec/*{bgColorError}*/ url(images/ui-bg_glass_95_fef1ec_1x400.png)/*{bgImgUrlError}*/ 50%/*{bgErrorXPos}*/ 50%/*{bgErrorYPos}*/ repeat-x/*{bgErrorRepeat}*/; color: #cd0a0a/*{fcError}*/; }
-.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a/*{fcError}*/; }
-.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a/*{fcError}*/; }
-.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
-.ui-priority-secondary, .ui-widget-content .ui-priority-secondary,  .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
-.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
-
-/* Icons
-----------------------------------*/
-
-/* states and images */
-.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; }
-.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; }
-.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsHeader}*/; }
-.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png)/*{iconsDefault}*/; }
-.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsHover}*/; }
-.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsActive}*/; }
-.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png)/*{iconsHighlight}*/; }
-.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png)/*{iconsError}*/; }
-
-/* positioning */
-.ui-icon-carat-1-n { background-position: 0 0; }
-.ui-icon-carat-1-ne { background-position: -16px 0; }
-.ui-icon-carat-1-e { background-position: -32px 0; }
-.ui-icon-carat-1-se { background-position: -48px 0; }
-.ui-icon-carat-1-s { background-position: -64px 0; }
-.ui-icon-carat-1-sw { background-position: -80px 0; }
-.ui-icon-carat-1-w { background-position: -96px 0; }
-.ui-icon-carat-1-nw { background-position: -112px 0; }
-.ui-icon-carat-2-n-s { background-position: -128px 0; }
-.ui-icon-carat-2-e-w { background-position: -144px 0; }
-.ui-icon-triangle-1-n { background-position: 0 -16px; }
-.ui-icon-triangle-1-ne { background-position: -16px -16px; }
-.ui-icon-triangle-1-e { background-position: -32px -16px; }
-.ui-icon-triangle-1-se { background-position: -48px -16px; }
-.ui-icon-triangle-1-s { background-position: -64px -16px; }
-.ui-icon-triangle-1-sw { background-position: -80px -16px; }
-.ui-icon-triangle-1-w { background-position: -96px -16px; }
-.ui-icon-triangle-1-nw { background-position: -112px -16px; }
-.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
-.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
-.ui-icon-arrow-1-n { background-position: 0 -32px; }
-.ui-icon-arrow-1-ne { background-position: -16px -32px; }
-.ui-icon-arrow-1-e { background-position: -32px -32px; }
-.ui-icon-arrow-1-se { background-position: -48px -32px; }
-.ui-icon-arrow-1-s { background-position: -64px -32px; }
-.ui-icon-arrow-1-sw { background-position: -80px -32px; }
-.ui-icon-arrow-1-w { background-position: -96px -32px; }
-.ui-icon-arrow-1-nw { background-position: -112px -32px; }
-.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
-.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
-.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
-.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
-.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
-.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
-.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
-.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
-.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
-.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
-.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
-.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
-.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
-.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
-.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
-.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
-.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
-.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
-.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
-.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
-.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
-.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
-.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
-.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
-.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
-.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
-.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
-.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
-.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
-.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
-.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
-.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
-.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
-.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
-.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
-.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
-.ui-icon-arrow-4 { background-position: 0 -80px; }
-.ui-icon-arrow-4-diag { background-position: -16px -80px; }
-.ui-icon-extlink { background-position: -32px -80px; }
-.ui-icon-newwin { background-position: -48px -80px; }
-.ui-icon-refresh { background-position: -64px -80px; }
-.ui-icon-shuffle { background-position: -80px -80px; }
-.ui-icon-transfer-e-w { background-position: -96px -80px; }
-.ui-icon-transferthick-e-w { background-position: -112px -80px; }
-.ui-icon-folder-collapsed { background-position: 0 -96px; }
-.ui-icon-folder-open { background-position: -16px -96px; }
-.ui-icon-document { background-position: -32px -96px; }
-.ui-icon-document-b { background-position: -48px -96px; }
-.ui-icon-note { background-position: -64px -96px; }
-.ui-icon-mail-closed { background-position: -80px -96px; }
-.ui-icon-mail-open { background-position: -96px -96px; }
-.ui-icon-suitcase { background-position: -112px -96px; }
-.ui-icon-comment { background-position: -128px -96px; }
-.ui-icon-person { background-position: -144px -96px; }
-.ui-icon-print { background-position: -160px -96px; }
-.ui-icon-trash { background-position: -176px -96px; }
-.ui-icon-locked { background-position: -192px -96px; }
-.ui-icon-unlocked { background-position: -208px -96px; }
-.ui-icon-bookmark { background-position: -224px -96px; }
-.ui-icon-tag { background-position: -240px -96px; }
-.ui-icon-home { background-position: 0 -112px; }
-.ui-icon-flag { background-position: -16px -112px; }
-.ui-icon-calendar { background-position: -32px -112px; }
-.ui-icon-cart { background-position: -48px -112px; }
-.ui-icon-pencil { background-position: -64px -112px; }
-.ui-icon-clock { background-position: -80px -112px; }
-.ui-icon-disk { background-position: -96px -112px; }
-.ui-icon-calculator { background-position: -112px -112px; }
-.ui-icon-zoomin { background-position: -128px -112px; }
-.ui-icon-zoomout { background-position: -144px -112px; }
-.ui-icon-search { background-position: -160px -112px; }
-.ui-icon-wrench { background-position: -176px -112px; }
-.ui-icon-gear { background-position: -192px -112px; }
-.ui-icon-heart { background-position: -208px -112px; }
-.ui-icon-star { background-position: -224px -112px; }
-.ui-icon-link { background-position: -240px -112px; }
-.ui-icon-cancel { background-position: 0 -128px; }
-.ui-icon-plus { background-position: -16px -128px; }
-.ui-icon-plusthick { background-position: -32px -128px; }
-.ui-icon-minus { background-position: -48px -128px; }
-.ui-icon-minusthick { background-position: -64px -128px; }
-.ui-icon-close { background-position: -80px -128px; }
-.ui-icon-closethick { background-position: -96px -128px; }
-.ui-icon-key { background-position: -112px -128px; }
-.ui-icon-lightbulb { background-position: -128px -128px; }
-.ui-icon-scissors { background-position: -144px -128px; }
-.ui-icon-clipboard { background-position: -160px -128px; }
-.ui-icon-copy { background-position: -176px -128px; }
-.ui-icon-contact { background-position: -192px -128px; }
-.ui-icon-image { background-position: -208px -128px; }
-.ui-icon-video { background-position: -224px -128px; }
-.ui-icon-script { background-position: -240px -128px; }
-.ui-icon-alert { background-position: 0 -144px; }
-.ui-icon-info { background-position: -16px -144px; }
-.ui-icon-notice { background-position: -32px -144px; }
-.ui-icon-help { background-position: -48px -144px; }
-.ui-icon-check { background-position: -64px -144px; }
-.ui-icon-bullet { background-position: -80px -144px; }
-.ui-icon-radio-off { background-position: -96px -144px; }
-.ui-icon-radio-on { background-position: -112px -144px; }
-.ui-icon-pin-w { background-position: -128px -144px; }
-.ui-icon-pin-s { background-position: -144px -144px; }
-.ui-icon-play { background-position: 0 -160px; }
-.ui-icon-pause { background-position: -16px -160px; }
-.ui-icon-seek-next { background-position: -32px -160px; }
-.ui-icon-seek-prev { background-position: -48px -160px; }
-.ui-icon-seek-end { background-position: -64px -160px; }
-.ui-icon-seek-start { background-position: -80px -160px; }
-/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
-.ui-icon-seek-first { background-position: -80px -160px; }
-.ui-icon-stop { background-position: -96px -160px; }
-.ui-icon-eject { background-position: -112px -160px; }
-.ui-icon-volume-off { background-position: -128px -160px; }
-.ui-icon-volume-on { background-position: -144px -160px; }
-.ui-icon-power { background-position: 0 -176px; }
-.ui-icon-signal-diag { background-position: -16px -176px; }
-.ui-icon-signal { background-position: -32px -176px; }
-.ui-icon-battery-0 { background-position: -48px -176px; }
-.ui-icon-battery-1 { background-position: -64px -176px; }
-.ui-icon-battery-2 { background-position: -80px -176px; }
-.ui-icon-battery-3 { background-position: -96px -176px; }
-.ui-icon-circle-plus { background-position: 0 -192px; }
-.ui-icon-circle-minus { background-position: -16px -192px; }
-.ui-icon-circle-close { background-position: -32px -192px; }
-.ui-icon-circle-triangle-e { background-position: -48px -192px; }
-.ui-icon-circle-triangle-s { background-position: -64px -192px; }
-.ui-icon-circle-triangle-w { background-position: -80px -192px; }
-.ui-icon-circle-triangle-n { background-position: -96px -192px; }
-.ui-icon-circle-arrow-e { background-position: -112px -192px; }
-.ui-icon-circle-arrow-s { background-position: -128px -192px; }
-.ui-icon-circle-arrow-w { background-position: -144px -192px; }
-.ui-icon-circle-arrow-n { background-position: -160px -192px; }
-.ui-icon-circle-zoomin { background-position: -176px -192px; }
-.ui-icon-circle-zoomout { background-position: -192px -192px; }
-.ui-icon-circle-check { background-position: -208px -192px; }
-.ui-icon-circlesmall-plus { background-position: 0 -208px; }
-.ui-icon-circlesmall-minus { background-position: -16px -208px; }
-.ui-icon-circlesmall-close { background-position: -32px -208px; }
-.ui-icon-squaresmall-plus { background-position: -48px -208px; }
-.ui-icon-squaresmall-minus { background-position: -64px -208px; }
-.ui-icon-squaresmall-close { background-position: -80px -208px; }
-.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
-.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
-.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
-.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
-.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
-.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
-
-
-/* Misc visuals
-----------------------------------*/
-
-/* Corner radius */
-.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; -khtml-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; }
-.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; -khtml-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; }
-.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; -khtml-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; }
-.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; -khtml-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; }
-
-/* Overlays */
-.ui-widget-overlay { background: #aaaaaa/*{bgColorOverlay}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlOverlay}*/ 50%/*{bgOverlayXPos}*/ 50%/*{bgOverlayYPos}*/ repeat-x/*{bgOverlayRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityOverlay}*/; }
-.ui-widget-shadow { margin: -8px/*{offsetTopShadow}*/ 0 0 -8px/*{offsetLeftShadow}*/; padding: 8px/*{thicknessShadow}*/; background: #aaaaaa/*{bgColorShadow}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlShadow}*/ 50%/*{bgShadowXPos}*/ 50%/*{bgShadowYPos}*/ repeat-x/*{bgShadowRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityShadow}*/; -moz-border-radius: 8px/*{cornerRadiusShadow}*/; -khtml-border-radius: 8px/*{cornerRadiusShadow}*/; -webkit-border-radius: 8px/*{cornerRad [...]
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/css/jquery.tipsy.css b/console/hawtio/src/main/webapp/plugin/css/jquery.tipsy.css
deleted file mode 100644
index a1e09ba..0000000
--- a/console/hawtio/src/main/webapp/plugin/css/jquery.tipsy.css
+++ /dev/null
@@ -1,126 +0,0 @@
-.tipsy {
-    font-size: 10px;
-    position: absolute;
-    padding: 5px;
-    word-wrap: break-word;
-    z-index: 100000;
-}
-
-.tipsy-inner {
-    background-color: #000;
-    color: #FFF;
-    max-width: 200px;
-    padding: 5px 8px 4px 8px;
-    text-align: center;
-}
-
-/* Rounded corners */
-.tipsy-inner {
-    border-radius: 3px;
-    -moz-border-radius: 3px;
-    -webkit-border-radius: 3px;
-}
-
-/* Uncomment for shadow */
-/*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/
-
-.tipsy-arrow {
-    position: absolute;
-    width: 0;
-    height: 0;
-    line-height: 0;
-    border: 5px dashed #000;
-}
-
-/* Rules to colour arrows */
-.tipsy-arrow-n {
-    border-bottom-color: #000;
-}
-
-.tipsy-arrow-s {
-    border-top-color: #000;
-}
-
-.tipsy-arrow-e {
-    border-left-color: #000;
-}
-
-.tipsy-arrow-w {
-    border-right-color: #000;
-}
-
-.tipsy-n .tipsy-arrow {
-    top: 0px;
-    left: 50%;
-    margin-left: -5px;
-    border-bottom-style: solid;
-    border-top: none;
-    border-left-color: transparent;
-    border-right-color: transparent;
-}
-
-.tipsy-nw .tipsy-arrow {
-    top: 0;
-    left: 10px;
-    border-bottom-style: solid;
-    border-top: none;
-    border-left-color: transparent;
-    border-right-color: transparent;
-}
-
-.tipsy-ne .tipsy-arrow {
-    top: 0;
-    right: 10px;
-    border-bottom-style: solid;
-    border-top: none;
-    border-left-color: transparent;
-    border-right-color: transparent;
-}
-
-.tipsy-s .tipsy-arrow {
-    bottom: 0;
-    left: 50%;
-    margin-left: -5px;
-    border-top-style: solid;
-    border-bottom: none;
-    border-left-color: transparent;
-    border-right-color: transparent;
-}
-
-.tipsy-sw .tipsy-arrow {
-    bottom: 0;
-    left: 10px;
-    border-top-style: solid;
-    border-bottom: none;
-    border-left-color: transparent;
-    border-right-color: transparent;
-}
-
-.tipsy-se .tipsy-arrow {
-    bottom: 0;
-    right: 10px;
-    border-top-style: solid;
-    border-bottom: none;
-    border-left-color: transparent;
-    border-right-color: transparent;
-}
-
-.tipsy-e .tipsy-arrow {
-    right: 0;
-    top: 50%;
-    margin-top: -5px;
-    border-left-style: solid;
-    border-right: none;
-    border-top-color: transparent;
-    border-bottom-color: transparent;
-}
-
-.tipsy-w .tipsy-arrow {
-    left: 0;
-    top: 50%;
-    margin-top: -5px;
-    border-right-style: solid;
-    border-left: none;
-    border-top-color: transparent;
-    border-bottom-color: transparent;
-}
diff --git a/console/hawtio/src/main/webapp/plugin/css/plugin.css b/console/hawtio/src/main/webapp/plugin/css/plugin.css
deleted file mode 100644
index 20fd0fb..0000000
--- a/console/hawtio/src/main/webapp/plugin/css/plugin.css
+++ /dev/null
@@ -1,994 +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.
-*/
-main-display > .span8 {
-  height: 100%;
-  position: relative;
-}
-
-ul.qdrListNodes > li > span {
-  padding: 6px 20px; 6px; 6px;
-  display: block;
-}
-
-.qdrList .gridStyle {
-    width: 20em;
-    margin-right: 0;
-    float: left;
-}
-
-
-.qdrList div.gridDetails {
-    width: auto;
-}
-
-div.gridDetails {
-    margin-left: 1em;
-}
-
-.selectedItems {
-    /* margin-left: 21em; */
-}
-
-.qdrListPane {
-    top: 110px;
-}
-
-.qdrListActions {
-    width: auto;
-    margin-left: 1em;
-}
-
-div.listAttrName {
-    padding-top: 5px;
-}
-
-div.listAttrName i.icon-bar-chart {
-    float: right;
-    margin: 3px 5px;
-}
-
-div.listAttrName i.icon-bar-chart.active, div.hastip i.icon-bar-chart.active, li.haschart i {
-    background-color: #AAFFAA;
-}
-
-div#main div ul.nav li a:not(.btn) {
-    background: initial !important;
-}
-
-div#main div ul.nav li.active a {
-    background-color: #f0f0ff !important;
-}
-
-div#main.qdr {
-    margin-top: 56px !important;
-}
-
-div.charts-header {
-  font-size: 1.2em;
-  color: #666666;
-  margin: 1em 0;
-}
-
-.selectedNode, .selectedAction, .selectedEntity {
-    font-weight: 600;
-    color: #606066;
-}
-
-.okButton {
-    text-align: center;
-    margin: 1em;
-}
-
-span.showChartsLink {
-    border: 1px solid blue;
-    padding: 1px 2px;
-}
-
-div.listGraphs p {
-    margin: 1em 0 2em 2em;
-    text-align: center;
-}
-
-div.centered {
-    text-align: center;
-    margin: 4em;
-}
-
-.modal-body.centered {
-	margin: 0;
-}
-
-/* dialog */
-div.aChart {
-    height: 200px;
-    width:  400px;
-    margin: 1em;
-}
-
-/* dashboard */
-div.aChart.hDash {
-	/* width: 21em; */
-	/* height: 17em; */
-	width: 100%;
-	height: 87%;
-	margin: 0;
-	padding: 0;
-
-}
-div.chartContainer {
-    float: left;
-	width: 100%;
-	height: 100%;
-	overflow: hidden;
-}
-
-/* the x and y axis lines */
-.d3Chart g.axis path.domain {
-    stroke-width: 1;
-    stroke: black;
-}
-
-/* the line surrounding the area chart */
-div.d3Chart path {
-/*    stroke: black; */
-    stroke-width: 0;
-/*	opacity: 0.5; */
-}
-
-/* the line above the area chart */
-/* the color gets overridden */
-div.d3Chart path.line {
-    stroke: steelblue;
-    stroke-width: 1.5;
-    fill: none;
-    opacity: 1;
-}
-
-.mo-rect {
-    fill: #ffffdd;
-    stroke: #f0f0f0;
-    stroke-width: 1;
-}
-
-.mo-guide {
-    fill: none;
-    stroke: #d0d0d0;
-    stroke-width: 2;
-    stroke-dasharray: 3,3;
-}
-
-div.d3Chart .title {
-    text-decoration: underline;
-}
-
-
-.axis line, .axis path {
-  fill: none;
-  shape-rendering: crispEdges;
-  stroke-width: 1;
-  stroke: #000000;
-}
-
-.axis line {
-  stroke: #C0C0C0;
-  stroke-dasharray: 1,1;
-  opacity: 0.5;
-}
-
-.y.axis text, .x.axis text, .focus text, div.d3Chart .title {
-    font-size: 12px;
-}
-
-.y.axis path {
-   stroke: #000;
- }
-
-.overlay {
-   fill: none;
-   pointer-events: all;
- }
-
-.focus circle {
-   fill: none;
-   stroke: steelblue;
- }
-.focus .fo-table {
-	/* box-shadow: 2px 2px 3px #EEE; */
-}
-
-div.d3Chart {
-    padding: 1em 0;
-    border: 1px solid #C0C0C0;
-}
-div.d3Chart.hDash {
-    border: 0px;
-}
-
-div.d3Chart .axis path {
-	display: inherit;
-}
-.c3-circle {
-	display: none;
-}
-
-.fo-table {
-	border: 1px solid darkgray;
-	background-color: white;
-	font-size: .85em;
-}
-
-.fo-table td {
-	padding: 4px;
-	border-left: 1px solid darkgray;
-}
-.fo-table tr.detail td {
-	padding: 1px 4px;
-}
-.fo-title {
-	color: white;
-	background-color: darkgray;
-}
-
-.fo-table-legend {
-	width: 8px;
-	height: 8px;
-	border: 1px solid black;
-	margin: 0 4px;
-	display: inline-block;
-}
-
-svg .legend {
-	dominant-baseline: central;
-}
-
-div.chartContainer div.aChart {
-    margin-top: 0.5em;
-}
-
-#list-controller .tree-header {
-    position: absolute;
-    height: auto;
-}
-
-#list-controller select {
-  height: 25px;
-  float: left;
-  padding: 0;
-}
-
-
-div#main.qdr div ul.nav li.active a {
-  background-color: #e0e0ff !important;
-  color: #000000;
-}
-
-div#main.qdr .selected, .box.selected {
-  color: #000000;
-  text-shadow: none;
-}
-
-/* the selected node on the list page */
-div.qdrList li.active, ul.qdrListNodes li.active {
-    background-color: #e0e0ff;
-}
-
-div.qdr-attributes span.dynatree-selected a {
-    background-color: #e0e0ff;
-}
-div.qdr-attributes.pane, div.qdr-topology.pane {
-	position: absolute;
-	margin-left: 10px;
-}
-div.qdr-overview.pane {
-	position: absolute;
-}
-div.qdr-topology.pane.left {
-	width: auto;
-  /*border-right: 1px solid lightgray; */
-}
-
-/* the selected row in the name table */
-div#main.qdr div.qdrList div.selected {
-  background-color: #e0e0ff !important;
-}
-
-#dialogChart, #dialogEditChart {
-    height: 200px;
-}
-
-.chartOptions .modal-body {
-  overflow-y: initial;
-}
-
-div.qdrCharts p.chartLabels button {
-    float: right;
-}
-
-div.qdrCharts p.chartLabels {
-     padding-right: 1em;;
- }
-
-p.dialogHeader {
-    text-align: center;
-}
-
-p.dialogHeader input {
-    margin-top: 10px;
-    width: 480px;
-}
-
-.ui-slider-tick {
-  position: absolute;
-  background-color: #666;
-  width: 2px;
-  height: 8px;
-  top: 12px;
-  z-index: -1;
-}
-
-label.rateGroup {
-    float: left;
-}
-
-div.chartOptions div.dlg-slider {
-    float: left;
-    width: 28em;
-    font-size: 14px;
-}
-
-div.chartOptions div.duration {
-  width: 35em !important;
-}
-
-div.chartOptions .slider {
-    margin-top: 1em;
-    margin-bottom: 1em;
-}
-
-input[type="radio"] {
-    margin-top: 0 !important;
-}
-
-div.chartOptions legend {
-    font-size: 1.2em;
-    font-weight: bold;
-    margin-bottom: 10px;
-}
-
-div.chartOptions tab > div {
-  margin-left: 1em;
-}
-
-div.chartOptions span.minicolors-swatch {
-    width: 14px;
-    height: 14px;
-}
-
-.minicolors-input {
-    width: 4em;
-    padding: 0 0 0 24px !important;
-}
-
-div.colorPicker div.colorText {
-	display: inline-block;
-	width: 10em;
-}
-div.colorPicker div:nth-of-type(1), /* first span under div.colorPicker */
- div.minicolors{
-    float:left;
-    margin-right: 0.5em;
-}
-
-div.chartOptions p.sep {
-    height: 1em;
-}
-
-ul.nav-tabs {
-    border-bottom: 1px solid #ddd !important;
-}
-
-.chartOptions ul.nav-tabs {
-    margin-bottom: 0px !important;
-}
-
-div.tabbable div.tab-content {
-    overflow: visible;
-}
-
-div.tabbable ul.nav-tabs > .active > a {
-  background-color: #f8f8f8;
-  border: 1px solid #ddd;
-  border-bottom-color: transparent;
-}
-
-
-div.tabbable .tab-pane {
-    background-color: #f8f8f8;
-    padding: 12px;
-    border-right: 1px solid #ddd;
-    border-left: 1px solid #ddd;
-    border-bottom: 1px solid #ddd;
-}
-div.dlg-large div.tabbable .tab-pane {
-	margin-left: 11em;
-}
-
-div.tabbable ul.nav-tabs {
-  margin-bottom: 0;
-}
-
-ul.qdrTopoModes {
-    position: relative;
-    top: -10px;
-}
-.overview.section {
-	/* width: 35em; */
-}
-.overview.section .ngGrid {
-	height: 12em !important;
-	min-height: 12em !important;
-}
-
-.overview.routers.section .ngGrid {
- 	height: 16em !important;
- 	min-height: 16em !important;
-}
-.overview.routers.section {
- 	/*width: 15em; */
- }
-
-.grid-align-value {
-	text-align: right;
-}
-
-.grid-align-value .ngCellText {
-	padding-right: 10px;
-}
-
-.overview .ngRow:hover {
-	background:#e0e0ff;
-}
-
-.overview-cell .ngCell:hover {
-	background:#e0e0ff;
-}
-.overview-cell .ngCell.col0:hover, .overview-cell .ngCell.col1:hover {
-	background: initial;
-}
-
-
-.qdr-overview.pane.left, .qdr-attributes.pane.left {
-	top: 104px;
-}
-.qdr-topology.pane.left {
-	top: 104px;
-}
-.qdr-overview.pane.left, .qdr-attributes.pane.left, .qdr-topology.pane.left {
-	left: 10px;
-}
-
-.treeContainer {
-	width: 100%;
-	float: left;
-}
-
-.pane-content {
-	overflow: auto;
-}
-
-#entityNames {
-    width: 20em;
-    float: left;
-}
-
-.treeDetails {
-	margin-left: 260px;
-}
-
-.gridStyle:not(.noHighlight) .ui-grid-row:hover .ui-grid-cell-contents {
-	background-color: #e0e0ff;
-}
-
-.ngCellText {
-	padding: 4px 0 0 4px;
-}
-
-.overview {
-	border-bottom: 1px solid #d4d4d4;
-}
-
-.ui-grid-row.ui-grid-row-selected > [ui-grid-row] > .ui-grid-cell {
-  background-color: #e0e0ff;
-}
-
-.tab-content .tab-pane {
-    background-color: #f8f8f8;
-    padding: 12px;
-    border-right: 1px solid #ddd;
-    border-left: 1px solid #ddd;
-    border-bottom: 1px solid #ddd;
-}
-
-div.chartOptions ul.nav-tabs > .active > a {
-  background-color: #f8f8f8;
-  border: 1px solid #ddd;
-  border-bottom-color: transparent;
-}
-
-div.chartOptions label:nth-of-type(2) {
-    margin-left: 1em;
-}
-div.chartOptions label {
-	font-weight: normal;
-	display: inline-block;
-}
-
-/*
-.form-horizontal .control-label {
-    float: left;
-    width: 160px;
-    padding-top: 5px;
-    text-align: right;
-}
-
-.form-horizontal .controls {
-    margin-left: 180px;
-}
-
-.form-horizontal input,  {
-    display: inline-block;
-    margin-bottom: 0;
-    vertical-align: middle;
-}
-
-input[type="text"], input[type="number"], input[type="password"] {
-    background-color: #ffffff;
-    border: 1px solid #cccccc;
-    -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-    -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-    -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
-    -moz-transition: border linear 0.2s, box-shadow linear 0.2s;
-    -o-transition: border linear 0.2s, box-shadow linear 0.2s;
-    transition: border linear 0.2s, box-shadow linear 0.2s;
-}
-
-input[type="text"], input[type="number"], input[type="password"] {
-    display: inline-block;
-    width: 200px;
-    padding: 4px 6px;
-    margin-bottom: 10px;
-    font-size: 14px;
-    line-height: 20px;
-    color: #555555;
-    vertical-align: middle;
-    -webkit-border-radius: 4px;
-    -moz-border-radius: 4px;
-    border-radius: 4px;
-}
-
-.login input[type="checkbox"] {
-	margin-top: 0.75em;
-}
-*/
-
-#dispatch-login-container {
-	/* width: 18.5em; */
-	margin-top: 2em;
-}
-/*
-div.login.container {
-	width: 550px;
-}
-*/
-
-
-#overtree .fancytree-container {
-	border: 0px;
-}
-
-#overtree span.fancytree-alert-icon.ui-icon-refresh {
-	background-position: -64px -80px;
-}
-#overtree span.fancytree-alert-icon.ui-icon-transfer-e-w {
-	background-position: -112px -80px;
-}
-
-#alerts {
-	position: fixed;
-	right: 0;
-	top: 0;
-	z-index: 100;
-}
-
-.alert-enter,
-.alert-leave,
-.alert-move {
-  -webkit-transition: 1s linear all;
-  -moz-transition: 1s linear all;
-  -o-transition: 1s linear all;
-  transition: 1s linear all;
-  position:relative;
-}
-
-.alert-enter {
-  left:-10px;
-  opacity:0;
-}
-.alert-enter.alert-enter-active {
-  left:0;
-  opacity:1;
-}
-
-.alert-leave {
-  left:0;
-  opacity:1;
-}
-.alert-leave.alert-leave-active {
-  left:-10px;
-  opacity:0;
-}
-
-.alert-move {
-  opacity:0.5;
-}
-.alert-move.alert-move-active {
-  opacity:1;
-}
-
-.overview .table-striped tr:hover  td {
-	background-color: #e0e0ff !important;
-}
-
-#entityNames div.ngViewport {
-	overflow-x: hidden;
-}
-
-.connect-column.connect-form {
-	width: 20em;
-}
-
-.chartLabels button a {
-	text-decoration: none;
-}
-
-.fancytree-ico-c.router .fancytree-icon {
-
-}
-
-.tabs-left .nav-tabs {
-	float: left;
-}
-.tabs-left .nav-tabs > li {
-/*	float: initial; */
-}
-
-div.modal.dlg-large {
-	width: 53em;
-}
-
-button.hdash-button a {
-	text-decoration: none;
-	color: #fff;
-}
-
-div.widget-body > div {
-	height: 100%;
-}
-
-div.qdrCharts {
-	height: 100%;
-}
-
-ul.dispatch-view {
-	margin-bottom: 0 !important;
-}
-
-.qdr-overview.pane.left span:not(.dynatree-has-children) .dynatree-icon:before,
-.qdr-attributes.pane.left span:not(.dynatree-has-children) .dynatree-icon:before {
-    color: green;
-}
-
-span:not(.dynatree-has-children).address .dynatree-icon:before,
-span:not(.dynatree-has-children).router\.address .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f0ac";
-}
-span:not(.dynatree-has-children).address.mobile .dynatree-icon:before,
-span:not(.dynatree-has-children).router\.address.mobile .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f109";
-}
-span:not(.dynatree-has-children).address.internal.mobile .dynatree-icon:before,
-span:not(.dynatree-has-children).router\.address.internal.mobile .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f0ac";
-}
-span:not(.dynatree-has-children).address.router .dynatree-icon:before,
-span:not(.dynatree-has-children).router\.address.router .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f047";
-}
-
-span.address-link .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f0ac";
-}
-
-span:not(.dynatree-has-children).connection.external .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f109";
-}
-span:not(.dynatree-has-children).connection.normal .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f08e";
-}
-span:not(.dynatree-has-children).connection.external.quiesced .dynatree-icon:before {
-  font-family: FontAwesome;
-	content: "\f14c";
-	color: red;
-}
-span:not(.dynatree-has-children).connection.inter-router .dynatree-icon:before {
-  font-family: FontAwesome;
-   content: "\f07e";
-}
-span:not(.dynatree-has-children).connection.router-control .dynatree-icon:before {
-  font-family: FontAwesome;
-   content: "\f013";
-}
-span:not(.dynatree-has-children).no-data .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f05e";
-  color: red !important;
-}
-span:not(.dynatree-has-children).loading .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f254";
-}
-span:not(.dynatree-has-children).connector .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f126";
-}
-span:not(.dynatree-has-children).container .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f16c";
-}
-span:not(.dynatree-has-children).log .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f0f6";
-}
-span:not(.dynatree-has-children).router\.node .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f013";
-}
-span:not(.dynatree-has-children).link.inter-router .dynatree-icon:before,
-span:not(.dynatree-has-children).router\.link.inter-router .dynatree-icon:before{
-  font-family: FontAwesome;
-  content: "\f07e";
-}
-span:not(.dynatree-has-children).link.router-control .dynatree-icon:before,
-span:not(.dynatree-has-children).router\.link.router-control .dynatree-icon:before{
-  font-family: FontAwesome;
-  content: "\f013";
-}
-span:not(.dynatree-has-children).link.endpoint .dynatree-icon:before,
-span:not(.dynatree-has-children).router\.link.endpoint .dynatree-icon:before{
-  font-family: FontAwesome;
-  content: "\f109";
-}
-span:not(.dynatree-has-children).link.console .dynatree-icon:before,
-span:not(.dynatree-has-children).router\.link.console .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f108";
-}
-span:not(.dynatree-has-children).listener .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f025";
-}
-span:not(.dynatree-has-children).connection .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f07e";
-}
-span:not(.dynatree-has-children).connection.console .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f108";
-}
-span:not(.dynatree-has-children).waypoint .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f0ec";
-}
-span:not(.dynatree-has-children).router .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f047";
-}
-span:not(.dynatree-has-children).fixedAddress .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f015";
-}
-span:not(.dynatree-has-children).linkRoutePattern .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f039";
-}
-span:not(.dynatree-has-children).allocator .dynatree-icon:before {
-  font-family: FontAwesome;
-  content: "\f170";
-}
-
-.ngCellText {
-/*    color: #333333; */
-}
-
-.changed {
-    color: #339933;
-}
-
-div.dispatch-router div.help {
-    width: auto;
-    padding: 1em;
-    background-color: lavender;
-    border-radius: 6px;
-    margin-top: 1em;
-    text-align: center;
-}
-
-div.operations tr:nth-child(even) {
-	background: #f3f3f3;
-}
-div.operations tr:nth-child(odd), div.operations tr:last-child {
-	background: #fff;
-}
-
-div.operations tr input {
-	margin: 0;
-	padding: 3px 6px;
-}
-div.operations table {
-    width: 100%;
-}
-div.operations th {
-    width: 50%;
-    border-bottom: 1px solid #cccccc;
-    text-align: left;
-}
-div.operations td:nth-child(odd), div.operations th:nth-child(odd) {
-	border-right: 1px solid #cccccc;
-}
-div.operations td:nth-child(odd) {
-	padding-left: 0;
-}
-div.operations td:nth-child(even), div.operations th:nth-child(even) {
-	padding-left: 5px;
-}
-div.operations th {
-	padding: 5px;
-}
-div.operations .tab-pane.active {
-    padding: 12px 12px 12px 0;
-}
-div.operations label {
-    padding-top: 4px;
-    margin-bottom: 4px;
-}
-.qdrListActions .ngGrid {
-	/*min-height: 40em;
-	height: 100%; */
-}
-div.qdrListActions .ngViewport {
-    height: initial !important;
-}
-
-div.operations .boolean {
-    padding-bottom: 0;
-}
-
-table.log-entry {
-    margin-bottom: 1em;
-    border-top: 1px solid black;
-}
-
-table.log-entry pre {
-    background-color: #f5f5f5;
-    color: inherit;
-    margin: 0;
-}
-
-circle.node.normal.console {
-    fill: lightcyan;
-}
-circle.node.artemis {
-    fill: lightgreen;
-}
-circle.node.route-container {
-    fill: orange;
-}
-
-text.console, text.on-demand, text.normal {
-	font-family: FontAwesome;
-	font-weight: normal;
-	font-size: 16px;
-}
-
-@font-face {
-    font-family:"Brokers";
-    src: url("brokers.ttf") /* TTF file for CSS3 browsers */
-}
-
-text.artemis {
-    font-family: Brokers;
-    font-size: 20px;
-    font-weight: bold;
-}
-
-text.qpid-cpp {
-    font-family: Brokers;
-    font-size: 18px;
-    font-weight: bold;
-}
-
-i.red {
-	color: red;
-}
-
-.qdrListActions div.delete {
-    width: 20em;
-    margin: auto;
-    border: 1px solid #eaeaea;
-    height: 5em;
-    padding: 4em;
-    background-color: #fcfcfc;
-}
-
-.btn:focus {
-    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
-}
-
-select:focus, input[type="file"]:focus, input[type="radio"]:focus, input[type="checkbox"]:focus {
-	outline:3px solid rgba(82, 168, 236, 0.6);
-    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
-    outline: 5px auto -webkit-focus-ring-color;
-    outline-offset: -2px;
-}
-
-btn.disabled, .btn[disabled] {
-    opacity: 0.35;
-}
-
-#dispatch-login-container .ng-invalid-range {
-	border-color: #e9322d !important;
-}
-
-div#durationSlider, div#rateSlider {
-	margin-top: 1em;
-}
-
-.list-grid {
-	padding-left: 10px;
-}
-
-.ngViewport.ng-scope {
-  height: auto !important;
-}
-
-div#list-controller {
-    padding-left: 300px;
-}
-
-.listening-on {
-    background-color: #CCFFCC;
-}
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/fonts/fontawesome-webfont.woff b/console/hawtio/src/main/webapp/plugin/fonts/fontawesome-webfont.woff
deleted file mode 100644
index dc35ce3..0000000
Binary files a/console/hawtio/src/main/webapp/plugin/fonts/fontawesome-webfont.woff and /dev/null differ
diff --git a/console/hawtio/src/main/webapp/plugin/fonts/fontawesome-webfont.woff2 b/console/hawtio/src/main/webapp/plugin/fonts/fontawesome-webfont.woff2
deleted file mode 100644
index 500e517..0000000
Binary files a/console/hawtio/src/main/webapp/plugin/fonts/fontawesome-webfont.woff2 and /dev/null differ
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrCharts.html b/console/hawtio/src/main/webapp/plugin/html/qdrCharts.html
deleted file mode 100644
index cb4f338..0000000
--- a/console/hawtio/src/main/webapp/plugin/html/qdrCharts.html
+++ /dev/null
@@ -1,82 +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.
--->
-<div class="main-display row-fluid qdrCharts" ng-controller="QDR.ChartsController">
-    <div ng-hide="dashLogin" ng-repeat="chart in svgCharts" class="chartContainer ">
-        <p class="chartLabels">
-            <button ng-click="editChart(chart)" title="Configure"><i class="icon-edit"></i></button>
-            <button ng-click="zoomChart(chart)" title="Zoom {{chart.zoomed ? 'in' : 'out'}}" ng-if="!chart.chart.request().nodeList"><i ng-class="chart.zoomed ? 'icon-zoom-in' : 'icon-zoom-out'"></i></button>
-        </p><div style="clear:both"></div>
-        <div id="{{chart.chart.id()}}" class="hDash aChart d3Chart"></div>
-    </div>
-    <div ng-init="chartsLoaded()"></div>
-    <div ng-show="dashLogin" class="centered alert alert-warning">
-        <p>You need to <a ng-href="{{loginHref}}">login</a> to Dispatch Router before viewing this chart.</p>
-    </div>
-</div>
-
-<!--
-    This is the template for the graph dialog that is displayed. It uses the
-    dialogCtrl controller in qdrCharts.js.
--->
-<script type="text/ng-template" id="chart-config-template.html">
-<div class="chartOptions">
-    <div class="modal-header">
-        <h3 class="modal-title">Chart {{chart.attr() | humanify}}</h3>
-    </div>
-    <div class="modal-body">
-        <div id="{{svgDivId}}" class="d3Chart"></div>
-        <tabset>
-            <tab heading="Type">
-                <legend>Chart type</legend>
-                <label><input type="radio" ng-model="dialogChart.type" value="value" /> Value Chart</label>
-                <label><input type="radio" ng-model="dialogChart.type" value="rate" /> Rate Chart</label>
-                <div class="dlg-slider" ng-show="dialogChart.type=='rate'">
-                    <span>Rate Window: {{rateWindow}} second{{rateWindow > 1 ? "s" : ""}}</span>
-                    <div id="rateSlider"></div>
-                </div>
-                <div style="clear:both;"> </div>
-            </tab>
-            <tab ng-hide="$parent.chart.aggregate()" heading="Colors">
-                <legend>Chart colors</legend>
-                <div class="colorPicker">
-                    <label>Line: <input id="lineColor" name="lineColor" type="color" /></label>
-                </div>
-                <div class="colorPicker">
-                    <label>Area: <input id="areaColor" name="areaColor" type="color" /></label>
-                </div>
-                <div style="clear:both;"> </div>
-            </tab>
-            <tab heading="Duration">
-                <legend>Chart duration</legend>
-                <div class="dlg-slider duration">
-                    <span>Show data for past {{dialogChart.visibleDuration}} minute{{dialogChart.visibleDuration > 1 ? "s" : ""}}</span>
-                    <div id="durationSlider"></div>
-                </div>
-                <div style="clear:both;"> </div>
-
-            </tab>
-        </tabset>
-    </div>
-    <div class="modal-footer">
-        <button class="btn btn-success" type="button" ng-click="apply()">Apply</button>
-        <button class="btn btn-primary" type="button" ng-click="okClick()">Close</button>
-    </div>
-</div>
-</script>
-
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrConnect.html b/console/hawtio/src/main/webapp/plugin/html/qdrConnect.html
deleted file mode 100644
index 412eab9..0000000
--- a/console/hawtio/src/main/webapp/plugin/html/qdrConnect.html
+++ /dev/null
@@ -1,97 +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.
--->
-<div class="row-fluid" ng-controller="QDR.SettingsController">
-      <div class="login container" ng-hide="connecting">
-          <div class="row" id="dispatch-login-container">
-              <div class="connect-column">
-                  <div class="alert alert-success">
-                      <p>
-                          Enter the address and a HTML-enabled port of a <strong><a href="http://qpid.apache.org/components/dispatch-router/" target="_blank">Qpid Dispatch Router</a></strong> to connect..
-                      </p>
-                      <p>
-                          If Autostart is checked, you will be automatically logged in to the router the next time you start the console.
-                      </p>
-
-                  </div>
-              </div>
-              <div class="connect-column connect-form">
-                  <form class="hawtio-form form-horizontal no-bottom-margin" novalidate ng-submit="connect()" name="settings">
-                      <fieldset>
-                          <div class="control-group">
-                              <label class="strong control-label">Address: </label>
-                              <div class="controls">
-                                  <input tabindex="1" type="text" ng-model="formEntity.address" placeholder="localhost" name="address" autofocus="autofocus" class="ng-pristine ng-valid ng-valid-required"></div>
-                          </div>
-                          <div class="control-group">
-                              <label tabindex="-1" class="control-label" title="Ports to connect to, by default 5673">Port: </label>
-                              <div class="controls">
-                                  <input tabindex="2" posint type="number" placeholder="5673" tooltip="Ports to connect to, by default 5673" ng-model="formEntity.port" name="port" title="Ports to connect to, by default 5673">
-                                  <span ng-show="settings.port.$error.range">Must be 1 through 65535</span>
-                              </div>
-                          </div>
-                          <div class="control-group">
-                              <label tabindex="-1" class="control-label" title="Username">Username: </label>
-                              <div class="controls">
-                                  <input tabindex="3" type="text" placeholder="username" 
-                                    tooltip="Username to use for authentication" 
-                                    ng-model="formEntity.username" 
-                                    name="username" 
-                                    title="Username">
-                              </div>
-                          </div>
-                          <div class="control-group">
-                              <label tabindex="-1" class="control-label" title="Password">Password: </label>
-                              <div class="controls">
-                                  <input tabindex="4" type="password" placeholder="password" 
-                                    tooltip="Password to use for authentication" 
-                                    ng-model="formEntity.password" 
-                                    name="password" 
-                                    title="Password">
-                              </div>
-                          </div>
-                          <div class="control-group">
-                              <label tabindex="-1" class="control-label" title="Whether or not the connection should be started as soon as you log into hawtio">Autostart: </label>
-                              <div class="controls">
-                                  <input tabindex="5" type="checkbox" 
-                                    tooltip="Whether or not the connection should be started as soon as you log into hawtio" 
-                                    ng-model="formEntity.autostart" 
-                                    name="autostart" 
-                                    title="Whether or not the connection should be started as soon as you log into hawtio"
-                              ></div>
-                          </div>
-                          <input tabindex="-1" type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;">
-                          <p></p>
-                          <div>
-                              <button type="submit" tabindex="4" class="btn btn-primary pull-right" ng-disabled="settings.$invalid">{{buttonText()}}</button>
-                          </div>
-                      </fieldset>
-                  </form>
-              </div>
-          </div>
-      </div>
-
-      <div class="centered" ng-show="connecting">
-        <i class="icon-spin icon-spinner icon-4x"></i>
-        <p>Please wait, connecting now...</p>
-      </div>
-      <div class="centered" ng-show="connectionError">
-        <p>There was a connection error: {{connectionErrorText}}</p>
-      </div>
-
-</div>
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrLayout.html b/console/hawtio/src/main/webapp/plugin/html/qdrLayout.html
deleted file mode 100644
index 208e390..0000000
--- a/console/hawtio/src/main/webapp/plugin/html/qdrLayout.html
+++ /dev/null
@@ -1,26 +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.
--->
-<ul class="nav nav-tabs connected dispatch-view" ng-controller="QDR.NavBarController">
-  <li ng-repeat="link in breadcrumbs" title="{{link.title}}" ng-show="isValid(link)" ng-class='{active : isActive(link.href), "pull-right" : isRight(link), haschart: hasChart(link)}'>
-    <a ng-href="{{link.href}}{{hash}}" ng-bind-html-unsafe="link.content"></a>
-  </li>
-</ul>
-<div class="row-fluid dispatch-router">
-  <div ng-view></div>
-</div>
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrList.html b/console/hawtio/src/main/webapp/plugin/html/qdrList.html
deleted file mode 100644
index 9a108e2..0000000
--- a/console/hawtio/src/main/webapp/plugin/html/qdrList.html
+++ /dev/null
@@ -1,93 +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.
--->
-
-<div id="list-controller" ng-controller="QDR.ListController"  ng-include="tmplListTree"></div>
-
-<script type="text/ng-template" id="listGrid.html">
-    <div class="row-fluid qdrListActions">
-        <ul class="nav nav-tabs">
-            <li ng-repeat="mode in modes" ng-show="isValid(mode)" ng-click="selectMode(mode)" ng-class="{active : isModeSelected(mode)}" title="{{mode.title}}" ng-bind-html-unsafe="mode.content"> </li>
-        </ul>
-        <h4>{{selectedRecordName}}</h4>
-        <div ng-show="currentMode.id === 'attributes'" class="selectedItems">
-            <div ng-show="selectedRecordName === selectedEntity" class="no-content">There are no {{selectedEntity | safePlural}}</div>
-            <div ng-hide="selectedRecordName === selectedEntity" ng-grid="details"></div>
-        </div>
-        <div ng-show="currentMode.id === 'delete'">
-            <div class="delete" ng-show="selectedRecordName !== selectedEntity">
-                <button class="btn btn-primary" ng-click="remove()">Delete</button> {{selectedRecordName}}
-            </div>
-            <div ng-hide="selectedRecordName !== selectedEntity">
-                There are no {{selectedEntity | safePlural}}
-            </div>
-        </div>
-        <div class="operations" ng-show="currentMode.id === 'operations'">
-            <fieldset ng-show="operation != ''">
-                <table>
-                    <tr>
-                        <th>Attribute</th>
-                        <th>Value</th>
-                    </tr>
-                <tr title="{{attribute.title}}" ng-repeat="attribute in detailFields">
-                    <td><label for="{{attribute.name}}">{{attribute.name | humanify}}</label></td>
-                    <!-- we can't do <input type="{angular expression}"> because... jquery throws an exception because... -->
-                    <td>
-                    <div ng-if="attribute.input == 'input'">
-                        <!-- ng-pattern="testPattern(attribute)" -->
-                        <div ng-if="attribute.type == 'number'"><input type="number" name="{{attribute.name}}" id="{{attribute.name}}" ng-model="attribute.rawValue" ng-required="attribute.required" ng-class="{required: attribute.required, unique: attribute.unique}" class="ui-widget-content ui-corner-all"/><span ng-if="attribute.required" title="required" class="required-indicator"></span><span ng-if="attribute.unique" title="unique" class="unique-indicator"></span></div>
-                        <div ng-if="attribute.type == 'text'"><input type="text" name="{{attribute.name}}" id="{{attribute.name}}" ng-model="attribute.attributeValue" ng-required="attribute.required" ng-class="{required: attribute.required, unique: attribute.unique}" class="ui-widget-content ui-corner-all"/><span ng-if="attribute.required" title="required" class="required-indicator"></span><span ng-if="attribute.unique" title="unique" class="unique-indicator"></span></div>
-                        <div ng-if="attribute.type == 'textarea'"><textarea name="{{attribute.name}}" id="{{attribute.name}}" ng-model="attribute.attributeValue" ng-required="attribute.required" ng-class="{required: attribute.required, unique: attribute.unique}" class="ui-widget-content ui-corner-all"></textarea><span ng-if="attribute.required" title="required" class="required-indicator"></span><span ng-if="attribute.unique" title="unique" class="unique-indicator"></span></div>
-                        <span ng-if="attribute.type == 'disabled'" >{{getAttributeValue(attribute)}}</span>
-                    </div>
-                    <div ng-if="attribute.input == 'select'">
-                        <select id="{{attribute.name}}" ng-model="attribute.selected" ng-required="attribute.required" ng-class="{required: attribute.required, unique: attribute.unique}" ng-options="item for item in attribute.rawtype track by item"></select>
-                        <span ng-if="attribute.required" title="required" class="required-indicator"></span><span ng-if="attribute.unique" title="unique" class="unique-indicator"></span>
-                    </div>
-                    <div ng-if="attribute.input == 'boolean'" class="boolean">
-                        <label><input type="radio" ng-model="attribute.rawValue" ng-value="true"> True</label>
-                        <label><input type="radio" ng-model="attribute.rawValue" ng-value="false"> False</label>
-                    </div>
-                    </td>
-                </tr>
-                <tr><td></td><td><button class="btn btn-primary" type="button" ng-click="ok()">{{operation | Pascalcase}}</button></td></tr>
-                </table>
-            </fieldset>
-        </div>
-        <div ng-show="currentMode.id === 'log'">
-            <div ng-if="logResults.length > 0">
-                <table class="log-entry" ng-repeat="entry in logResults track by $index">
-                    <tr>
-                        <td align="left" colspan="2">{{entry.time}}</td>
-                    </tr>
-                    <tr>
-                        <td>Type</td><td>{{entry.type}}</td>
-                    </tr>
-                    <tr>
-                        <td>Source</td><td>{{entry.source}}:{{entry.line}}</td>
-                    </tr>
-                    <tr>
-                        <td valign="middle">Message</td><td valign="middle"><pre>{{entry.message}}</pre></td>
-                    </tr>
-                </table>
-            </div>
-            <div ng-if="logResults.length == 0 && !fetchingLog">No log entries for {{selectedRecordName}}</div>
-            <div ng-if="fetchingLog">Fetching logs for {{selectedRecordName}}</div>
-        </div>
-    </div>
-</script>
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrOverview.html b/console/hawtio/src/main/webapp/plugin/html/qdrOverview.html
deleted file mode 100644
index 6c848c5..0000000
--- a/console/hawtio/src/main/webapp/plugin/html/qdrOverview.html
+++ /dev/null
@@ -1,210 +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.
--->
-<div id="overview-controller" ng-controller="QDR.OverviewController" ng-include="tmplOverviewTree"></div>
-<script type="text/ng-template" id="overviewGrid.html">
-    <div class="gridDetails" ng-include="template.url"></div>
-</script>
-
-
-<!-- the following scripts are content that gets loaded into the above div that has the temple.url -->
-<script type="text/ng-template" id="routers.html">
-    <div class="row-fluid">
-        <h3>Routers</h3>
-        <div class="overview">
-            <div class="gridStyle" ng-grid="allRouters"></div>
-        </div>
-    </div>
-</script>
-<script type="text/ng-template" id="router.html">
-    <div class="row-fluid">
-        <h3>Router {{router.data.title}} attributes</h3>
-        <div class="gridStyle noHighlight" ng-grid="routerGrid"></div>
-    </div>
-</script>
-
-<script type="text/ng-template" id="addresses.html">
-    <div class="row-fluid">
-        <h3>Addresses</h3>
-        <div class="overview">
-            <div class="gridStyle" ng-grid="addressesGrid"></div>
-        </div>
-    </div>
-</script>
-<script type="text/ng-template" id="address.html">
-    <div class="row-fluid">
-        <ul class="nav nav-tabs">
-            <li ng-repeat="mode in gridModes" ng-click="selectMode(mode,'Address')" ng-class="{active : isModeSelected(mode,'Address')}" title="{{mode.title}}" ng-bind-html-unsafe="mode.content"> </li>
-        </ul>
-        <div ng-if="isModeVisible('Address','attributes')" class="selectedItems">
-            <h3>Address {{Address.data.title}}</h3>
-            <div class="gridStyle noHighlight" ng-grid="addressGrid"></div>
-        </div>
-        <div ng-if="isModeVisible('Address','links')" class="selectedItems">
-            <h3>Links for address {{Address.data.title}}</h3>
-            <div class="gridStyle" ng-grid="linksGrid"></div>
-        </div>
-    </div>
-</script>
-
-<script type="text/ng-template" id="links.html">
-    <div class="row-fluid">
-        <h3>Links <button type='button' ng-click="filterToggle()" class='btn btn-secondary btn-filter'>Filter</button></h3>
-        <div id="linkFilter">
-            <div class="filter-title">
-                <h6>Filter links</h6>
-                <button ng-click="filterToggle()" type="button" class="btn btn-primary filter-close">x</button>
-            </div>
-            <div class="formLine"><label for="hideConsoles">Hide console links</label><input name="hideConsoles" id="hideConsoles" type="checkbox" ng-model="filter.hideConsoles"/></div>
-            <div class="formLine"><label for="endpointOnly">Endpoints only</label><input name="linkTypes" id="endpointOnly" type="radio" ng-model="filter.endpointsOnly" value="true"/>
-                <label for="allLinks">All link types</label><input name="linkTypes" id="allLinks" type="radio" ng-model="filter.endpointsOnly" value="false"/></div>
-        </div>
-        <div class="gridStyle" ng-grid="linksGrid"></div>
-    </div>
-</script>
-<script type="text/ng-template" id="link.html">
-    <div class="row-fluid">
-        <h3>Link {{Link.data.title}}</h3>
-        <div class="gridStyle noHighlight" ng-grid="linkGrid"></div>
-    </div>
-</script>
-
-<script type="text/ng-template" id="connections.html">
-    <div class="row-fluid">
-        <h3>Connections</h3>
-        <div class="overview">
-            <div class="gridStyle" ng-grid="allConnectionGrid"></div>
-        </div>
-    </div>
-</script>
-<script type="text/ng-template" id="connection.html">
-    <div class="row-fluid">
-        <ul class="nav nav-tabs">
-            <li ng-repeat="mode in gridModes" ng-click="selectMode(mode,'Connection')" ng-class="{active : isModeSelected(mode,'Connection')}" title="{{mode.title}}" ng-bind-html-unsafe="mode.content"> </li>
-        </ul>
-        <div ng-if="isModeVisible('Connection','attributes')" class="selectedItems">
-            <h3>Connection {{Connection.data.title}}</h3>
-            <div class="gridStyle noHighlight" ng-grid="connectionGrid"></div>
-        </div>
-        <div ng-if="isModeVisible('Connection','links')" class="selectedItems">
-            <h3>Links for connection {{Connection.data.title}}</h3>
-            <div class="gridStyle" ng-grid="linksGrid"></div>
-        </div>
-    </div>
-</script>
-
-<script type="text/ng-template" id="titleHeaderCellTemplate.html">
-    <div title="{{col.displayName}}" class="ngHeaderSortColumn {{col.headerClass}}" ng-style="{'cursor': col.cursor}" ng-class="{ 'ngSorted': !noSortVisible }">
-        <div ng-click="col.sort($event)" ng-class="'colt' + col.index" class="ngHeaderText">{{col.displayName}}</div>
-        <div class="ngSortButtonDown" ng-show="col.showSortButtonDown()"></div>
-        <div class="ngSortButtonUp" ng-show="col.showSortButtonUp()"></div>
-        <div class="ngSortPriority">{{col.sortPriority}}</div>
-    </div>
-</script>
-<script type="text/ng-template" id="titleCellTemplate.html">
-    <div title="{{row.entity[col.field]}}" class="ngCellText">{{row.entity[col.field]}}</div>
-</script>
-<script type="text/ng-template" id="logs.html">
-    <div class="row-fluid">
-        <h3>Recent log events</h3>
-        <div class="overview">
-            <div class="gridStyle" ng-grid="allLogGrid"></div>
-        </div>
-    </div>
-</script>
-<script type="text/ng-template" id="logModule.html">
-    <div class="row-fluid">
-        <h3>{{logModule.module}} events</h3>
-        <div class="overview-cell">
-            <div class="gridStyle" ng-grid="logModuleGrid"></div>
-        </div>
-    </div>
-</script>
-<script type="text/ng-template" id="log.html">
-    <div class="row-fluid">
-        <h3>{{log.data.title}}</h3>
-        <div ng-if="logFields.length > 0">
-            <table class="log-entry" ng-repeat="entry in logFields track by $index">
-                <tr>
-                    <td>Router</td><td>{{entry.nodeId}}</td>
-                </tr>
-                <tr>
-                    <td align="left" colspan="2">{{entry.time}}</td>
-                </tr>
-                <tr>
-                    <td>Source</td><td>{{entry.source}}:{{entry.line}}</td>
-                </tr>
-                <tr>
-                    <td valign="middle">Message</td><td valign="middle"><pre>{{entry.message}}</pre></td>
-                </tr>
-            </table>
-        </div>
-        <div ng-if="logFields.length == 0">No log entries for {{log.data.title}}</div>
-    </div>
-</script>
-
-<script type="text/ng-template" id="linkRowTemplate.html">
-    <div ng-class="{linkDirIn: row.getProperty('linkDir') == 'in', linkDirOut: row.getProperty('linkDir') == 'out'}">
-        <div ng-style="{ 'cursor': row.cursor }" ng-repeat="col in renderedColumns" ng-class="col.colIndex()" class="ngCell {{col.cellClass}}">
-            <div class="ngVerticalBar" ng-style="{height: rowHeight}" ng-class="{ ngVerticalBarVisible: !$last }">&nbsp;</div>
-            <div ng-cell></div>
-        </div>
-    </div>
-</script>
-
-<script type="text/ng-template" id="linkAggTemplate.html">
-    <div ng-click='row.toggleExpand(); saveGroupState()' ng-style='rowStyle(row)' class='ngAggregate ng-scope' style='top: 0px; height: 48px; left: 0px;'>
-    <span class='ngAggregateText ng-binding'>
-            {{row.label CUSTOM_FILTERS}} ({{row.totalChildren()}} {{AggItemsLabel}})
-        </span>
-    <div ng-class="{true: 'ngAggArrowCollapsed', false: 'ngAggArrowExpanded'}[row.collapsed]"></div>
-    </div>
-</script>
-
-<script type="text/ng-template" id="viewLogs.html">
-    <div class="modal-header">
-        <h3 class="modal-title">Logs for {{nodeName}} {{module}}:{{level | humanify}}</h3>
-    </div>
-    <div class="modal-body">
-        <div ng-if="loading == false">
-            <div class="log-details" ng-if="logFields.length > 0">
-                <table class="log-entry" ng-repeat="entry in logFields track by $index">
-                    <tr>
-                        <td>Router</td><td>{{entry.nodeId}}</td>
-                    </tr>
-                    <tr>
-                        <td align="left" colspan="2">{{entry.time}}</td>
-                    </tr>
-                    <tr>
-                        <td>Source</td><td>{{entry.source}}:{{entry.line}}</td>
-                    </tr>
-                    <tr>
-                        <td valign="middle">Message</td><td valign="middle"><pre>{{entry.message}}</pre></td>
-                    </tr>
-                </table>
-            </div>
-            <div ng-if="logFields.length == 0">No log entries</div>
-        </div>
-        <div ng-if="loading == true">
-            Loading...
-        </div>
-    </div>
-    <div class="modal-footer">
-        <button class="btn btn-primary" type="button" ng-click="ok()">Close</button>
-    </div>
-</script>
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrSchema.html b/console/hawtio/src/main/webapp/plugin/html/qdrSchema.html
deleted file mode 100644
index 33f6951..0000000
--- a/console/hawtio/src/main/webapp/plugin/html/qdrSchema.html
+++ /dev/null
@@ -1,21 +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.
--->
-<div class="main-display row-fluid" ng-controller="QDR.SchemaController">
-    <div id="schema"></div>
-</div>
diff --git a/console/hawtio/src/main/webapp/plugin/html/qdrTopology.html b/console/hawtio/src/main/webapp/plugin/html/qdrTopology.html
deleted file mode 100644
index 496d2ac..0000000
--- a/console/hawtio/src/main/webapp/plugin/html/qdrTopology.html
+++ /dev/null
@@ -1,67 +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.
--->
-<div class="qdrTopology row-fluid" ng-controller="QDR.TopologyController">
-    <div class="qdr-topology pane left" ng-controller="QDR.TopologyFormController">
-        <div id="topologyForm" ng-class="{selected : isSelected()}">
-            <!-- <div ng-repeat="form in forms" ng-show="isVisible(form)" ng-class='{selected : isSelected(form)}'> -->
-            <div ng-show="form == 'router'">
-                <h4>Router Info</h4>
-                <div class="gridStyle" ng-grid="topoGridOptions"></div>
-            </div>
-            <div ng-show="form == 'connection'">
-                <h4>Connection Info</h4>
-                <div class="gridStyle" ng-grid="topoGridOptions"></div>
-            </div>
-        </div>
-        <button ng-if="panelVisible" ng-click="hideLeftPane()" class="hideLeft" title="Hide"><i class="icon-step-backward"></i></button>
-        <button ng-if="!panelVisible" ng-click="showLeftPane()" class="hideLeft" title="Show"><i class="icon-step-forward"></i></button>
-    </div>
-    <div class="panel-adjacent">
-        <div id="topology"><!-- d3 toplogy here --></div>
-        <div id="crosssection"><!-- d3 pack here --></div>
-        <div id="node_context_menu" class="contextMenu">
-            <ul>
-                <li class="na" ng-class="{'force-display': !isFixed()}" ng-click="setFixed(true)">Freeze in place</li>
-                <li class="na" ng-class="{'force-display': isFixed()}" ng-click="setFixed(false)">Unfreeze</li>
-            </ul>
-        </div>
-        <div id="svg_legend"></div>
-        <div id="multiple_details">
-            <h4 class="grid-title">Connections</h4>
-            <div class="gridStyle" ng-grid="multiDetails"></div>
-         </div>
-        <div id="link_details">
-            <h4 class="grid-title">Links</h4>
-            <div class="gridStyle" ng-grid="linkDetails"></div>
-        </div>
-    </div>
-</div>
-
-
-<script type="text/ng-template" id="titleHeaderCellTemplate.html">
-    <div title="{{col.displayName}}" class="ngHeaderSortColumn {{col.headerClass}}" ng-style="{'cursor': col.cursor}" ng-class="{ 'ngSorted': !noSortVisible }">
-        <div ng-click="col.sort($event)" ng-class="'colt' + col.index" class="ngHeaderText">{{col.displayName}}</div>
-        <div class="ngSortButtonDown" ng-show="col.showSortButtonDown()"></div>
-        <div class="ngSortButtonUp" ng-show="col.showSortButtonUp()"></div>
-        <div class="ngSortPriority">{{col.sortPriority}}</div>
-    </div>
-</script>
-<script type="text/ng-template" id="titleCellTemplate.html">
-    <div title="{{row.entity[col.field]}}" class="ngCellText">{{row.entity[col.field]}}</div>
-</script>
diff --git a/console/hawtio/src/main/webapp/plugin/html/tmplListChart.html b/console/hawtio/src/main/webapp/plugin/html/tmplListChart.html
deleted file mode 100644
index b3c866d..0000000
--- a/console/hawtio/src/main/webapp/plugin/html/tmplListChart.html
+++ /dev/null
@@ -1,31 +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
--->
-
-<div class="modal-header">
-    <h3 class="modal-title">Chart {{chart.attr() | humanify}}</h3>
-</div>
-<div class="modal-body">
-    <div id="{{svgDivId}}" class="d3Chart"></div>
-</div>
-<div class="modal-footer">
-        <span>
-            <div class="btn btn-success hdash-button" ng-click="addHChart()" title="Add this chart to a dashboard"><a ng-href="{{addToDashboardLink()}}"><i class="icon-share"></i> Add this chart to a dashboard</a></div>
-        </span>
-    <button class="btn btn-primary" type="button" ng-click="ok()">Close</button>
-</div>
\ No newline at end of file
diff --git a/console/hawtio/src/main/webapp/plugin/html/tmplListTree.html b/console/hawtio/src/main/webapp/plugin/html/tmplListTree.html
deleted file mode 100644
index 710ff0a..0000000
--- a/console/hawtio/src/main/webapp/plugin/html/tmplListTree.html
+++ /dev/null
@@ -1,40 +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
--->
-
-<div class="qdr-attributes pane left" position="left" width="300">
-    <div class="pane-wrapper">
-        <div class="pane-header-wrapper">
-            <div class="tree-header"><select ng-options="node as node.name for node in nodes" ng-model="currentNode" ng-change="selectNode(currentNode)"></select></div>
-            <div ng-hide="largeNetwork" ng-if="showExpandCollapseTree()" class="expand-collapse">
-                <i class="icon-chevron-down clickable" title="Expand all nodes" ng-click="expandAll()"></i>
-                <i class="icon-chevron-up clickable" title="Unexpand all nodes" ng-click="contractAll()"></i>
-            </div>
-        </div>
-        <div class="pane-viewport">
-            <div class="pane-content">
-                <div class="treeContainer">
-                    <div id="entityTree" onSelect="onTreeSelected" hideRoot="true"></div>
-                    <div ng-init="treeReady()"></div>
-                </div>
-            </div>
-        </div>
-        <div class="pane-bar"></div>
-    </div>
-</div>
-<div class="list-grid" ng-include="'listGrid.html'"></div>
diff --git a/console/hawtio/src/main/webapp/plugin/html/tmplOverviewTree.html b/console/hawtio/src/main/webapp/plugin/html/tmplOverviewTree.html
deleted file mode 100644
index 6cc149e..0000000
--- a/console/hawtio/src/main/webapp/plugin/html/tmplOverviewTree.html
+++ /dev/null
@@ -1,35 +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
--->
-
-<script type="text/ng-template" id="overviewheader.html">
-    <div class="expand-collapse">
-        <div ng-if="showExpandCollapseTree()" >
-            <i class="icon-chevron-down clickable" title="Expand all nodes" ng-click="expandAll()"></i>
-            <i class="icon-chevron-up clickable" title="Unexpand all nodes" ng-click="contractAll()"></i>
-        </div>
-    </div>
-</script>
-
-<hawtio-pane class="qdr-overview" position="left" width="300" header="overviewheader.html">
-    <div class="treeContainer">
-        <div id="overtree"></div>
-    </div>
-</hawtio-pane>
-<ng-include src="'overviewGrid.html'"></ng-include>
-<div ng-init="overviewLoaded()"></div>
diff --git a/console/hawtio/src/main/webapp/plugin/js/dispatchPlugin.js b/console/hawtio/src/main/webapp/plugin/js/dispatchPlugin.js
deleted file mode 100644
index 854fe60..0000000
--- a/console/hawtio/src/main/webapp/plugin/js/dispatchPlugin.js
+++ /dev/null
@@ -1,297 +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.
-*/
-/**
- * @module QDR
- * @main QDR
- *
- * The main entry point for the QDR module
- *
- */
-var QDR = (function(QDR) {
-
-  /**
-   * @property pluginName
-   * @type {string}
-   *
-   * The name of this plugin
-   */
-  QDR.pluginName = 'dispatch_hawtio_console';
-  QDR.pluginRoot = "/" + QDR.pluginName;
-  /**
-   * @property log
-   * @type {Logging.Logger}
-   *
-   * This plugin's logger instance
-   */
-  QDR.log = Logger.get('QDR');
-
-  /**
-   * @property contextPath
-   * @type {string}
-   *
-   * The top level path of this plugin on the server
-   *
-   */
-  QDR.contextPath = "/dispatch-hawtio-console/";
-
-  /**
-   * @property templatePath
-   * @type {string}
-   *
-   * The path to this plugin's partials
-   */
-  QDR.templatePath = QDR.contextPath + "plugin/html/";
-
-  QDR.SETTINGS_KEY = 'QDRSettings';
-  QDR.LAST_LOCATION = "QDRLastLocationHawt";
-
-  /**
-   * @property module
-   * @type {object}
-   *
-   * This plugin's angularjs module instance.  This plugin only
-   * needs hawtioCore to run, which provides services like
-   * workspace, viewRegistry and layoutFull used by the
-   * run function
-   */
-  QDR.module = angular.module(QDR.pluginName, ['bootstrap', 'hawtio-ui', 'hawtio-forms', 'ui.bootstrap.dialog', 'hawtioCore'])
-      .config(function($routeProvider) {
-        /**
-         * Here we define the route for our plugin.  One note is
-         * to avoid using 'otherwise', as hawtio has a handler
-         * in place when a route doesn't match any routes that
-         * routeProvider has been configured with.
-         */
-     $routeProvider
-      .when(QDR.pluginRoot, {
-        templateUrl: QDR.templatePath + 'qdrConnect.html'
-      })
-      .when(QDR.pluginRoot + '/', {
-        templateUrl: QDR.templatePath + 'qdrConnect.html'
-      })
-      .when(QDR.pluginRoot + '/connect', {
-        templateUrl: QDR.templatePath + 'qdrConnect.html'
-      })
-      .when(QDR.pluginRoot + '/overview', {
-        templateUrl: QDR.templatePath + 'qdrOverview.html'
-      })
-      .when(QDR.pluginRoot + '/topology', {
-        templateUrl: QDR.templatePath + 'qdrTopology.html'
-      })
-      .when(QDR.pluginRoot + '/list', {
-        templateUrl: QDR.templatePath + 'qdrList.html'
-      })
-      .when(QDR.pluginRoot + '/schema', {
-        templateUrl: QDR.templatePath + 'qdrSchema.html'
-      })
-      .when(QDR.pluginRoot + '/charts', {
-        templateUrl: QDR.templatePath + 'qdrCharts.html'
-      })
-      })
-    .config(function ($compileProvider) {
-      var cur = $compileProvider.urlSanitizationWhitelist();
-      $compileProvider.urlSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|blob):/);
-      cur = $compileProvider.urlSanitizationWhitelist();
-    })
-    .config(function( $controllerProvider, $provide, $compileProvider ) {
-
-    })
-    .filter('to_trusted', function($sce){
-      return function(text) {
-        return $sce.trustAsHtml(text);
-      };
-      })
-      .filter('humanify', function (QDRService) {
-      return function (input) {
-        return QDRService.humanify(input);
-      };
-    })
-    .filter('shortName', function () {
-      return function (name) {
-        var nameParts = name.split('/')
-        return nameParts.length > 1 ? nameParts[nameParts.length-1] : name;
-      };
-    })
-   .filter('pretty', function () {
-      return function (str) {
-        var formatComma = d3.format(",");
-        if (!isNaN(parseFloat(str)) && isFinite(str))
-          return formatComma(str);
-        return str;
-      };
-    })
-    .filter('Pascalcase', function () {
-          return function (str) {
-        if (!str)
-          return "";
-              return str.replace(/(\w)(\w*)/g,
-                        function(g0,g1,g2){return g1.toUpperCase() + g2.toLowerCase();});
-          }
-    })
-    .filter('safePlural', function () {
-          return function (str) {
-        var es = ['x', 'ch', 'ss', 'sh']
-        for (var i=0; i<es.length; ++i) {
-          if (str.endsWith(es[i]))
-            return str + 'es'
-        }
-        if (str.endsWith('y'))
-          return str.substr(0, str.length-2) + 'ies'
-        if (str.endsWith('s'))
-          return str;
-        return str + 's'
-          }
-    })
-/*
-  QDR.module.config(['$locationProvider', function($locationProvider) {
-        $locationProvider.html5Mode(true);
-    }]);
-*/
-  /**
-   * Here we define any initialization to be done when this angular
-   * module is bootstrapped.  In here we do a number of things:
-   *
-   * 1.  We log that we've been loaded (kinda optional)
-   * 2.  We load our .css file for our views
-   * 3.  We configure the viewRegistry service from hawtio for our
-   *     route; in this case we use a pre-defined layout that uses
-   *     the full viewing area
-   * 4.  We configure our top-level tab and provide a link to our
-   *     plugin.  This is just a matter of adding to the workspace's
-   *     topLevelTabs array.
-   */
-  QDR.module.run(function(workspace, viewRegistry, layoutFull, $route, $rootScope, $location, $timeout, localStorage, QDRService, QDRChartService) {
-
-    QDR.queue = d3.queue;
-
-    QDR.log.info("*************creating Dispatch Console************");
-    var curPath = $location.path()
-    QDR.log.info("curPath is " + curPath)
-    var lastLocation = localStorage[QDR.LAST_LOCATION] || "connect"
-    if (lastLocation.startsWith(QDR.pluginRoot)) {
-      lastLocation = lastLocation.substr(QDR.pluginRoot.length+1)
-      if (lastLocation === '')
-        lastLocation = "overview"
-    }
-    if (curPath.startsWith(QDR.pluginRoot)) {
-      $location.path(QDR.pluginRoot + "/connect");
-      var org = curPath.substr(QDR.pluginRoot.length + 1)
-      if (org === '') {
-        org = lastLocation
-      }
-      if (curPath === QDR.pluginRoot && (!org || org.length===0 || org !== 'connect')) {
-        org = lastLocation
-      }
-      if (org === 'connect')
-        $location.search('org', null);
-      else if (org && org.length > 0) {
-        $location.search('org', org)
-      }
-    }
-
-    Core.addCSS(QDR.contextPath + "plugin/css/dispatch.css");
-    Core.addCSS(QDR.contextPath + "plugin/css/plugin.css");
-    Core.addCSS(QDR.contextPath + "plugin/css/jquery.tipsy.css");
-    Core.addCSS(QDR.contextPath + "plugin/css/jquery-ui.css");
-    Core.addCSS(QDR.contextPath + "plugin/css/font-awesome.min.css");
-
-    // tell hawtio that we have our own custom layout for
-    // our view
-    viewRegistry[QDR.pluginName] = QDR.templatePath + "qdrLayout.html";
-
-    QDRService.addUpdatedAction("initChartService", function() {
-      QDRService.delUpdatedAction("initChartService")
-      QDRChartService.init(); // initialize charting service after we are connected
-    });
-
-    var settings = angular.fromJson(localStorage[QDR.SETTINGS_KEY]);
-    if (settings && settings.autostart) {
-      QDRService.addConnectAction(function() {
-        QDRService.addDisconnectAction( function () {
-          $location.path(QDR.pluginRoot + "/connect");
-          $location.replace();
-          $rootScope.$apply();
-        })
-        QDRService.getSchema(function () {
-          QDR.log.debug("got schema after connection")
-          QDRService.addUpdatedAction("initialized", function () {
-            QDRService.delUpdatedAction("initialized")
-            QDR.log.debug("got initial topology")
-            $timeout(function() {
-              if ($location.path().startsWith(QDR.pluginRoot)) {
-                var lastLocation = localStorage[QDR.LAST_LOCATION] || "/overview"
-                $location.search('org', null)
-                $location.path(lastLocation);
-                $location.replace();
-                $rootScope.$apply();
-              }
-            })
-          })
-          QDR.log.debug("requesting a topology")
-          QDRService.setUpdateEntities([])
-          QDRService.topology.get()
-        })
-      });
-      QDRService.connect(settings);
-    }
-    $rootScope.$on('$routeChangeSuccess', function() {
-      var path = $location.path();
-      if (path.startsWith(QDR.pluginRoot)) {
-        if (path !== QDR.pluginRoot && path !== (QDR.pluginRoot + "/") && path !== (QDR.pluginRoot + "/connect")) {
-          localStorage[QDR.LAST_LOCATION] = path;
-QDR.log.info("saving page changed to " + path)
-        }
-      }
-    });
-
-    $rootScope.$on( "$routeChangeStart", function(event, next, current) {
-      if (next && next.templateUrl == QDR.templatePath + "qdrConnect.html" && QDRService.connected) {
-        // clicked connect from another dispatch page
-        if (current && current.loadedTemplateUrl && current.loadedTemplateUrl.startsWith(QDR.contextPath)) {
-          return;
-        }
-        // clicked the Dispatch Router top level tab from a different plugin
-        var lastLocation = localStorage[QDR.LAST_LOCATION] || (QDR.pluginRoot + "/overview");
-        // show the last page visited
-QDR.log.info("showing dispatch tab: going to page " + lastLocation)
-        $location.path(lastLocation)
-      }
-      });
-
-    workspace.topLevelTabs.push({
-      id: "dispatch",
-      content: "Dispatch Router",
-      title: "Dispatch console",
-      isValid: function(workspace) { return true; },
-      href: function() { return "#/" + QDR.pluginName; },
-      isActive: function(workspace) { return workspace.isLinkActive(QDR.pluginName); }
-    });
-
-  });
-
-  return QDR;
-
-})(QDR || {});
-
-// tell the hawtio plugin loader about our plugin so it can be
-// bootstrapped with the rest of angular
-hawtioPluginLoader.addModule(QDR.pluginName);
-
-
-
diff --git a/console/hawtio/src/main/webapp/plugin/js/navbar.js b/console/hawtio/src/main/webapp/plugin/js/navbar.js
deleted file mode 100644
index 5125748..0000000
--- a/console/hawtio/src/main/webapp/plugin/js/navbar.js
+++ /dev/null
@@ -1,301 +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.
-*/
-/**
- * @module QDR
- */
-var QDR = (function (QDR) {
-
-  /**
-   * @property breadcrumbs
-   * @type {{content: string, title: string, isValid: isValid, href: string}[]}
-   *
-   * Data structure that defines the sub-level tabs for
-   * our plugin, used by the navbar controller to show
-   * or hide tabs based on some criteria
-   */
-  QDR.breadcrumbs = [
-    {
-        content: '<i class="icon-cogs"></i> Connect',
-        title: "Connect to a router",
-        isValid: function () { return true; },
-        href: "#" + QDR.pluginRoot + "/connect"
-    },
-    {
-        content: '<i class="icon-home"></i> Overview',
-        title: "View router overview",
-        isValid: function (QDRService) { return QDRService.isConnected(); },
-        href: "#" + QDR.pluginRoot + "/overview"
-      },
-    {
-        content: '<i class="icon-list "></i> Entities',
-        title: "View the attributes of the router entities",
-        isValid: function (QDRService) { return QDRService.isConnected(); },
-        href: "#" + QDR.pluginRoot + "/list"
-      },
-    {
-        content: '<i class="icon-star-empty"></i> Topology',
-        title: "View router network topology",
-        isValid: function (QDRService) { return QDRService.isConnected(); },
-        href: "#" + QDR.pluginRoot + "/topology"
-      },
-    {
-        content: '<i class="icon-bar-chart"></i> Charts',
-        title: "View charts",
-        isValid: function (QDRService, $location) { return QDRService.isConnected() && QDR.isStandalone; },
-        href: "#/charts"
-    },
-    {
-        content: '<i class="icon-align-left"></i> Schema',
-        title: "View dispatch schema",
-        isValid: function (QDRService) { return QDRService.isConnected(); },
-        href: "#" + QDR.pluginRoot + "/schema",
-        right: true
-      }
-  ];
-  /**
-   * @function NavBarController
-   *
-   * @param $scope
-   * @param workspace
-   *
-   * The controller for this plugin's navigation bar
-   *
-   */
-  QDR.module.controller("QDR.NavBarController", ['$scope', 'QDRService', 'QDRChartService', '$routeParams', '$location', function($scope, QDRService, QDRChartService, $routeParams, $location) {
-    $scope.breadcrumbs = QDR.breadcrumbs;
-    $scope.isValid = function(link) {
-      return link.isValid(QDRService, $location);
-    };
-
-    $scope.isActive = function(href) {
-    // highlight the connect tab if we are on the root page
-    if (($location.path() === QDR.pluginRoot) && (href.split("#")[1] === QDR.pluginRoot + "/connect"))
-      return true
-        return href.split("#")[1] == $location.path();
-    };
-
-    $scope.isRight = function (link) {
-        return angular.isDefined(link.right);
-    };
-
-    $scope.hasChart = function (link) {
-        if (link.href == "#/charts") {
-            return QDRChartService.charts.some(function (c) { return c.dashboard });
-        }
-    }
-
-  $scope.isDashboardable = function () {
-    return  ($location.path().indexOf("schema") < 0 && $location.path().indexOf("connect") < 0);
-  }
-
-  $scope.addToDashboardLink = function () {
-    var href = "#" + $location.path();
-    var size = angular.toJson({
-                size_x: 2,
-                size_y: 2
-              });
-
-        var routeParams = angular.toJson($routeParams);
-        var title = "Dispatch Router";
-      return "/hawtio/#/dashboard/add?tab=dashboard" +
-            "&href=" + encodeURIComponent(href) +
-            "&routeParams=" + encodeURIComponent(routeParams) +
-            "&title=" + encodeURIComponent(title) +
-            "&size=" + encodeURIComponent(size);
-    };
-
-  }]);
-
-  // controller for the edit/configure chart dialog
-  QDR.module.controller("QDR.ChartDialogController", function($scope, QDRChartService, $location, dialog, chart, updateTick, dashboard, adding) {
-    var dialogSvgChart = null;
-    $scope.svgDivId = "dialogEditChart";    // the div id for the svg chart
-
-    var updateTimer = null;
-    $scope.chart = chart;  // the underlying chart object from the dashboard
-    $scope.dialogChart = $scope.chart.copy(); // the chart object for this dialog
-    $scope.userTitle = $scope.chart.title();
-
-    $scope.$watch('userTitle', function(newValue, oldValue) {
-    if (newValue !== oldValue) {
-      $scope.dialogChart.title(newValue);
-      dialogSvgChart.tick($scope.svgDivId);
-    }
-    })
-    $scope.$watch("dialogChart.areaColor", function (newValue, oldValue) {
-      if (newValue !== oldValue) {
-        if (dialogSvgChart)
-         dialogSvgChart.tick($scope.svgDivId);
-      }
-    })
-    $scope.$watch("dialogChart.lineColor", function (newValue, oldValue) {
-      if (newValue !== oldValue) {
-        if (dialogSvgChart)
-          dialogSvgChart.tick($scope.svgDivId);
-      }
-    })
-    $scope.$watch("dialogChart.type", function (newValue, oldValue) {
-      if (newValue !== oldValue) {
-        if (dialogSvgChart)
-          dialogSvgChart.tick($scope.svgDivId);
-      }
-    })
-
-    // the stored rateWindow is in milliseconds, but the slider is in seconds
-    $scope.rateWindow = $scope.chart.rateWindow / 1000;
-
-    $scope.addChartsPage = function () {
-      QDRChartService.addDashboard(dialogSvgChart.chart);
-    };
-
-    $scope.showChartsPage = function () {
-      cleanup();
-      dialog.close(true);
-      $location.path(QDR.pluginRoot + "/charts");
-    };
-
-    var cleanup = function () {
-      if (updateTimer) {
-        clearTimeout(updateTimer);
-        updateTimer = null;
-      }
-      if (!$scope.isOnChartsPage())
-        QDRChartService.unRegisterChart($scope.dialogChart);     // remove the chart
-    }
-    $scope.okClick = function () {
-      cleanup();
-      dialog.close(true);
-    };
-
-    var initRateSlider = function () {
-      if (document.getElementById('rateSlider')) {
-        $( "#rateSlider" ).slider({
-          value: $scope.rateWindow,
-          min: 1,
-          max: 10,
-          step: 1,
-          slide: function( event, ui ) {
-            $scope.rateWindow = ui.value;
-            $scope.dialogChart.rateWindow = ui.value * 1000;
-            $scope.$apply();
-            if (dialogSvgChart)
-              dialogSvgChart.tick($scope.svgDivId);
-          }
-        });
-      } else {
-        setTimeout(initRateSlider, 100)
-      }
-    }
-    initRateSlider();
-
-    var initDurationSlider = function () {
-      if (document.getElementById('durationSlider')) {
-        $( "#durationSlider" ).slider({
-          value: $scope.dialogChart.visibleDuration,
-          min: 1,
-          max: 10,
-          step: 1,
-          slide: function( event, ui ) {
-            $scope.visibleDuration = $scope.dialogChart.visibleDuration = ui.value;
-            $scope.$apply();
-            if (dialogSvgChart)
-              dialogSvgChart.tick($scope.svgDivId);
-          }
-        });
-      } else {
-        setTimeout(initDurationSlider, 100)
-      }
-    }
-    initDurationSlider();
-
-    $scope.adding = function () {
-      return adding
-    }
-
-    $scope.isOnChartsPage = function () {
-      if (adding)
-        return dialogSvgChart ? dialogSvgChart.chart.dashboard : false;
-      else
-        return $scope.chart.dashboard
-    }
-
-    // handle the Apply button click
-    // update the dashboard chart's properties
-    $scope.apply = function () {
-      $scope.chart.areaColor = $scope.dialogChart.areaColor;
-      $scope.chart.lineColor = $scope.dialogChart.lineColor;
-      $scope.chart.type = $scope.dialogChart.type;
-      $scope.chart.rateWindow = $scope.rateWindow * 1000;
-      $scope.chart.title($scope.dialogChart.title());
-      $scope.chart.visibleDuration = $scope.dialogChart.visibleDuration;
-      QDRChartService.saveCharts();
-      if (typeof updateTick === "function")
-        updateTick();
-    }
-
-    // add a new chart to the dashboard based on the current dialog settings
-    $scope.copyToDashboard = function () {
-        var chart = $scope.dialogChart.copy();
-        // set the new chart's dashboard state
-        QDRChartService.addDashboard(chart);
-        // notify the chart controller that it needs to display a new chart
-        dashboard.addChart(chart);
-    }
-
-    // update the chart on the popup dialog
-    var updateDialogChart = function () {
-      // draw the chart using the current data
-      if (dialogSvgChart)
-          dialogSvgChart.tick($scope.svgDivId);
-
-      // draw the chart again in 1 second
-      var updateRate = localStorage['updateRate'] ? localStorage['updateRate'] : 5000;
-      if (updateTimer)
-      clearTimeout(updateTimer);
-        updateTimer = setTimeout(updateDialogChart, updateRate);
-    }
-
-    var showChart = function () {
-      // ensure the div for our chart is loaded in the dom
-      var div = angular.element("#" + $scope.svgDivId);
-      if (!div.width()) {
-        setTimeout(showChart, 100);
-        return;
-      }
-      dialogSvgChart = new QDRChartService.AreaChart($scope.dialogChart);
-      $('input[name=lineColor]').val($scope.dialogChart.lineColor);
-      $('input[name=areaColor]').val($scope.dialogChart.areaColor);
-      $('input[name=areaColor]').on('input', function (e) {
-        $scope.dialogChart.areaColor = $(this).val();
-        updateDialogChart()
-      })
-      $('input[name=lineColor]').on('input', function (e) {
-        $scope.dialogChart.lineColor = $(this).val();
-        updateDialogChart()
-      })
-      if (updateTimer)
-        clearTimeout(updateTimer);
-          updateDialogChart();
-    }
-    showChart();
-  });
-
-  return QDR;
-
-} (QDR || {}));
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrChartService.js b/console/hawtio/src/main/webapp/plugin/js/qdrChartService.js
deleted file mode 100644
index cc64981..0000000
--- a/console/hawtio/src/main/webapp/plugin/js/qdrChartService.js
+++ /dev/null
@@ -1,1154 +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.
-*/
-/**
- * @module QDR
- */
-var QDR = (function(QDR) {
-
-  // The QDR chart service handles periodic gathering data for charts and displaying the charts
-  QDR.module.factory("QDRChartService", ['$rootScope', 'QDRService', '$http', '$resource', '$location',
-    function($rootScope, QDRService, $http, $resource, $location) {
-
-      var instance = 0; // counter for chart instances
-      var bases = [];
-      var findBase = function(name, attr, request) {
-        for (var i = 0; i < bases.length; ++i) {
-          var base = bases[i];
-          if (base.equals(name, attr, request))
-            return base;
-        }
-        return null;
-      }
-
-      function ChartBase(name, attr, request) {
-        // the base chart attributes
-        this.name = name; // the record's "name" field
-        this.attr = attr; // the record's attr field to chart
-        this.request = request; // the associated request that fetches the data
-
-        // copy the savable properties to an object
-        this.copyProps = function(o) {
-          o.name = this.name;
-          o.attr = this.attr;
-          this.request.copyProps(o);
-        }
-
-        this.equals = function(name, attr, request) {
-          return (this.name == name && this.attr == attr && this.request.equals(request));
-        }
-      };
-
-      // Object that represents a visible chart
-      // There can be multiple of these per ChartBase (eg. one rate  and one value chart)
-      function Chart(opts, request) { //name, attr, cinstance, request) {
-
-        var base = findBase(opts.name, opts.attr, request);
-        if (!base) {
-          base = new ChartBase(opts.name, opts.attr, request);
-          bases.push(base);
-        }
-        this.base = base;
-        this.instance = angular.isDefined(opts.instance) ? opts.instance : ++instance;
-        this.dashboard = false; // is this chart on the dashboard page
-        this.hdash = false; // is this chart on the hawtio dashboard page
-        this.hreq = false; // has this hdash chart been requested
-        this.type = opts.type ? opts.type : "value"; // value or rate
-        this.rateWindow = opts.rateWindow ? opts.rateWindow : 1000; // calculate the rate of change over this time interval. higher == smother graph
-        this.areaColor = "#cbe7f3"; // the chart's area color when not an empty string
-        this.lineColor = "#058dc7"; // the chart's line color when not an empty string
-        this.visibleDuration = opts.visibleDuration ? opts.visibleDuration : 10; // number of minutes of data to show (<= base.duration)
-        this.userTitle = null; // user title overrides title()
-
-        // generate a unique id for this chart
-        this.id = function() {
-            var name = this.name()
-            var nameparts = name.split('/');
-            if (nameparts.length == 2)
-              name = nameparts[1];
-            var key = QDRService.nameFromId(this.request().nodeId) + this.request().entity + name + this.attr() + "_" + this.instance + "_" + (this.request().aggregate ? "1" : "0");
-            // remove all characters except letters,numbers, and _
-            return key.replace(/[^\w]/gi, '')
-          }
-          // copy the savable properties to an object
-        this.copyProps = function(o) {
-          o.type = this.type;
-          o.rateWindow = this.rateWindow;
-          o.areaColor = this.areaColor;
-          o.lineColor = this.lineColor;
-          o.visibleDuration = this.visibleDuration;
-          o.userTitle = this.userTitle;
-          o.dashboard = this.dashboard;
-          o.hdash = this.hdash;
-          o.instance = this.instance;
-          this.base.copyProps(o);
-        }
-        this.name = function(_) {
-          if (!arguments.length) return this.base.name;
-          this.base.name = _;
-          return this;
-        }
-        this.attr = function(_) {
-          if (!arguments.length) return this.base.attr;
-          this.base.attr = _;
-          return this;
-        }
-        this.nodeId = function(_) {
-          if (!arguments.length) return this.base.request.nodeId;
-          this.base.request.nodeId = _;
-          return this;
-        }
-        this.entity = function(_) {
-          if (!arguments.length) return this.base.request.entity;
-          this.base.request.entity = _;
-          return this;
-        }
-        this.aggregate = function(_) {
-          if (!arguments.length) return this.base.request.aggregate;
-          this.base.request.aggregate = _;
-          return this;
-        }
-        this.request = function(_) {
-          if (!arguments.length) return this.base.request;
-          this.base.request = _;
-          return this;
-        }
-        this.data = function() {
-          return this.base.request.data(this.base.name, this.base.attr); // refernce to chart's data array
-        }
-        this.interval = function(_) {
-          if (!arguments.length) return this.base.request.interval;
-          this.base.request.interval = _;
-          return this;
-        }
-        this.duration = function(_) {
-          if (!arguments.length) return this.base.request.duration;
-          this.base.request.duration = _;
-          return this;
-        }
-        this.title = function(_) {
-          var name = this.request().aggregate ? 'Aggregate' : QDRService.nameFromId(this.nodeId());
-          var computed = name +
-            " " + QDRService.humanify(this.attr()) +
-            " - " + this.name()
-          if (!arguments.length) return this.userTitle || computed;
-
-          // don't store computed title in userTitle
-          if (_ === computed)
-            _ = null;
-          this.userTitle = _;
-          return this;
-        }
-        this.title_short = function(_) {
-          if (!arguments.length) return this.userTitle || this.name();
-          return this;
-        }
-        this.copy = function() {
-            var chart = self.registerChart({
-              nodeId: this.nodeId(),
-              entity: this.entity(),
-              name: this.name(),
-              attr: this.attr(),
-              interval: this.interval(),
-              forceCreate: true,
-              aggregate: this.aggregate(),
-              hdash: this.hdash
-            })
-            chart.type = this.type;
-            chart.areaColor = this.areaColor;
-            chart.lineColor = this.lineColor;
-            chart.rateWindow = this.rateWindow;
-            chart.visibleDuration = this.visibleDuration;
-            chart.userTitle = this.userTitle;
-            return chart;
-          }
-          // compare to a chart
-        this.equals = function(c) {
-          return (c.instance == this.instance &&
-            c.base.equals(this.base.name, this.base.attr, this.base.request) &&
-            c.type == this.type &&
-            c.rateWindow == this.rateWindow &&
-            c.areaColor == this.areaColor &&
-            c.lineColor == this.lineColor)
-        }
-      }
-
-      // Object that represents the management request to fetch and store data for multiple charts
-      function ChartRequest(opts) { //nodeId, entity, name, attr, interval, aggregate) {
-        this.duration = opts.duration || 10; // number of minutes to keep the data
-        this.nodeId = opts.nodeId; // eg amqp:/_topo/0/QDR.A/$management
-        this.entity = opts.entity; // eg .router.address
-        // sorted since the responses will always be sorted
-        this.aggregate = opts.aggregate; // list of nodeIds for aggregate charts
-        this.datum = {}; // object containing array of arrays for each attr
-        // like {attr1: [[date,value],[date,value]...], attr2: [[date,value]...]}
-
-        this.interval = opts.interval || 1000; // number of milliseconds between updates to data
-        this.setTimeoutHandle = null; // used to cancel the next request
-        // copy the savable properties to an object
-
-        this.data = function(name, attr) {
-          if (this.datum[name] && this.datum[name][attr])
-            return this.datum[name][attr]
-          return null;
-        }
-        this.addAttrName = function(name, attr) {
-          if (Object.keys(this.datum).indexOf(name) == -1) {
-            this.datum[name] = {}
-          }
-          if (Object.keys(this.datum[name]).indexOf(attr) == -1) {
-            this.datum[name][attr] = [];
-          }
-        }
-        this.addAttrName(opts.name, opts.attr)
-
-        this.copyProps = function(o) {
-          o.nodeId = this.nodeId;
-          o.entity = this.entity;
-          o.interval = this.interval;
-          o.aggregate = this.aggregate;
-          o.duration = this.duration;
-        }
-
-        this.removeAttr = function(name, attr) {
-          if (this.datum[name]) {
-            if (this.datum[name][attr]) {
-              delete this.datum[name][attr]
-            }
-          }
-          return this.attrs().length;
-        }
-
-        this.equals = function(r, entity, aggregate) {
-          if (arguments.length == 3) {
-            var o = {
-              nodeId: r,
-              entity: entity,
-              aggregate: aggregate
-            }
-            r = o;
-          }
-          return (this.nodeId === r.nodeId && this.entity === r.entity && this.aggregate == r.aggregate)
-        }
-        this.names = function() {
-          return Object.keys(this.datum)
-        }
-        this.attrs = function() {
-          var attrs = {}
-          Object.keys(this.datum).forEach(function(name) {
-            Object.keys(this.datum[name]).forEach(function(attr) {
-              attrs[attr] = 1;
-            })
-          }, this)
-          return Object.keys(attrs);
-        }
-      };
-
-      // Below here are the properties and methods available on QDRChartService
-      var self = {
-        charts: [], // list of charts to gather data for
-        chartRequests: [], // the management request info (multiple charts can be driven off of a single request
-
-        init: function() {
-          self.loadCharts();
-          QDRService.addDisconnectAction(function() {
-            self.charts.forEach(function(chart) {
-              self.unRegisterChart(chart, true)
-            })
-            QDRService.addConnectAction(self.init);
-          })
-        },
-
-        findChartRequest: function(nodeId, entity, aggregate) {
-          var ret = null;
-          self.chartRequests.some(function(request) {
-            if (request.equals(nodeId, entity, aggregate)) {
-              ret = request;
-              return true;
-            }
-          })
-          return ret;
-        },
-
-        findCharts: function(opts) { //name, attr, nodeId, entity, hdash) {
-          if (!opts.hdash)
-            opts.hdash = false; // rather than undefined
-          return self.charts.filter(function(chart) {
-            return (chart.name() == opts.name &&
-              chart.attr() == opts.attr &&
-              chart.nodeId() == opts.nodeId &&
-              chart.entity() == opts.entity &&
-              chart.hdash == opts.hdash)
-          });
-        },
-
-        delChartRequest: function(request) {
-          for (var i = 0; i < self.chartRequests.length; ++i) {
-            var r = self.chartRequests[i];
-            if (request.equals(r)) {
-              QDR.log.debug("removed request: " + request.nodeId + " " + request.entity);
-              self.chartRequests.splice(i, 1);
-              self.stopCollecting(request);
-              return;
-            }
-          }
-        },
-
-        delChart: function(chart, skipSave) {
-          var foundBases = 0;
-          for (var i = 0; i < self.charts.length; ++i) {
-            var c = self.charts[i];
-            if (c.base === chart.base)
-              ++foundBases;
-            if (c.equals(chart)) {
-              self.charts.splice(i, 1);
-              if (chart.dashboard && !skipSave)
-                self.saveCharts();
-            }
-          }
-          if (foundBases == 1) {
-            var baseIndex = bases.indexOf(chart.base)
-            bases.splice(baseIndex, 1);
-          }
-        },
-
-        registerChart: function(opts) { //nodeId, entity, name, attr, interval, instance, forceCreate, aggregate, hdash) {
-          var request = self.findChartRequest(opts.nodeId, opts.entity, opts.aggregate);
-          if (request) {
-            // add any new attr or name to the list
-            request.addAttrName(opts.name, opts.attr)
-          } else {
-            // the nodeId/entity did not already exist, so add a new request and chart
-            QDR.log.debug("added new request: " + opts.nodeId + " " + opts.entity);
-            request = new ChartRequest(opts); //nodeId, entity, name, attr, interval, aggregate);
-            self.chartRequests.push(request);
-            self.startCollecting(request);
-          }
-          var charts = self.findCharts(opts); //name, attr, nodeId, entity, hdash);
-          var chart;
-          if (charts.length == 0 || opts.forceCreate) {
-            if (!opts.use_instance && opts.instance)
-              delete opts.instance;
-            chart = new Chart(opts, request) //opts.name, opts.attr, opts.instance, request);
-            self.charts.push(chart);
-          } else {
-            chart = charts[0];
-          }
-          return chart;
-        },
-
-        // remove the chart for name/attr
-        // if all attrs are gone for this request, remove the request
-        unRegisterChart: function(chart, skipSave) {
-          // remove the chart
-
-          // TODO: how do we remove charts that were added to the hawtio dashboard but then removed?
-          // We don't get a notification that they were removed. Instead, we could just stop sending
-          // the request in the background and only send the request when the chart's tick() event is triggered
-          //if (chart.hdash) {
-          //  chart.dashboard = false;
-          //  self.saveCharts();
-          //    return;
-          //}
-
-          for (var i = 0; i < self.charts.length; ++i) {
-            var c = self.charts[i];
-            if (chart.equals(c)) {
-              var request = chart.request();
-              self.delChart(chart, skipSave);
-              if (request) {
-                // see if any other charts use this attr
-                for (var i = 0; i < self.charts.length; ++i) {
-                  var c = self.charts[i];
-                  if (c.attr() == chart.attr() && c.request().equals(chart.request()))
-                    return;
-                }
-                // no other charts use this attr, so remove it
-                if (request.removeAttr(chart.name(), chart.attr()) == 0) {
-                  self.stopCollecting(request);
-                  self.delChartRequest(request);
-                }
-              }
-            }
-          }
-          if (!skipSave)
-            self.saveCharts();
-        },
-
-        stopCollecting: function(request) {
-          if (request.setTimeoutHandle) {
-            clearTimeout(request.setTimeoutHandle);
-            request.setTimeoutHandle = null;
-          }
-        },
-
-        startCollecting: function(request) {
-          // Using setTimeout instead of setInterval because the response may take longer than interval
-          request.setTimeoutHandle = setTimeout(self.sendChartRequest, request.interval, request);
-        },
-        shouldRequest: function(request) {
-          // see if any of the charts associated with this request have either dialog, dashboard, or hreq
-          return self.charts.some(function(chart) {
-            return (chart.dashboard || chart.hreq) || (!chart.dashboard && !chart.hdash);
-          });
-        },
-        // send the request
-        sendChartRequest: function(request, once) {
-          if (!once && !self.shouldRequest(request)) {
-            request.setTimeoutHandle = setTimeout(self.sendChartRequest, request.interval, request)
-            return;
-          }
-
-          // ensure the response has the name field so we can associate the response values with the correct chart
-          var attrs = request.attrs();
-          if (attrs.indexOf("name") == -1)
-            attrs.push("name");
-
-          // this is called when the response is received
-          var saveResponse = function(nodeId, entity, response) {
-            if (!response || !response.attributeNames)
-              return;
-            //QDR.log.debug("got chart results for " + nodeId + " " + entity);
-            // records is an array that has data for all names
-            var records = response.results;
-            if (!records)
-              return;
-
-            var now = new Date();
-            var cutOff = new Date(now.getTime() - request.duration * 60 * 1000);
-            // index of the "name" attr in the response
-            var nameIndex = response.attributeNames.indexOf("name");
-            if (nameIndex < 0)
-              return;
-
-            var names = request.names();
-            // for each record returned, find the name/attr for this request and save the data with this timestamp
-            for (var i = 0; i < records.length; ++i) {
-              var name = records[i][nameIndex];
-              // if we want to store the values for some attrs for this name
-              if (names.indexOf(name) > -1) {
-                attrs.forEach(function(attr) {
-                  var data = request.data(name, attr) // get a reference to the data array
-                  if (data) {
-                    var attrIndex = response.attributeNames.indexOf(attr)
-                    if (request.aggregate) {
-                      data.push([now, response.aggregates[i][attrIndex].sum, response.aggregates[i][attrIndex].detail])
-                    } else {
-                      data.push([now, records[i][attrIndex]])
-                    }
-                    // expire the old data
-                    while (data[0][0] < cutOff) {
-                      data.shift();
-                    }
-                  }
-                })
-              }
-            }
-          }
-          if (request.aggregate) {
-            var nodeList = QDRService.nodeIdList()
-            QDRService.getMultipleNodeInfo(nodeList, request.entity, attrs, saveResponse, request.nodeId);
-          } else {
-            QDRService.fetchEntity(request.nodeId, request.entity, attrs, saveResponse);
-          }
-          // it is now safe to schedule another request
-          if (once)
-            return;
-          request.setTimeoutHandle = setTimeout(self.sendChartRequest, request.interval, request)
-        },
-
-        numCharts: function() {
-          return self.charts.filter(function(chart) {
-            return chart.dashboard
-          }).length;
-          //return self.charts.length;
-        },
-
-        isAttrCharted: function(nodeId, entity, name, attr) {
-          var charts = self.findCharts({
-              name: name,
-              attr: attr,
-              nodeId: nodeId,
-              entity: entity
-            })
-            // if any of the matching charts are on the dashboard page, return true
-          return charts.some(function(chart) {
-            return (chart.dashboard)
-          });
-        },
-
-        addHDash: function(chart) {
-          chart.hdash = true;
-          self.saveCharts();
-        },
-        delHDash: function(chart) {
-          chart.hdash = false;
-          self.saveCharts();
-        },
-        addDashboard: function(chart) {
-          chart.dashboard = true;
-          self.saveCharts();
-        },
-        delDashboard: function(chart) {
-          chart.dashboard = false;
-          self.saveCharts();
-        },
-        // save the charts to local storage
-        saveCharts: function() {
-          var charts = [];
-          var minCharts = [];
-
-          self.charts.forEach(function(chart) {
-            var minChart = {};
-            // don't save chart unless it is on the dashboard
-            if (chart.dashboard || chart.hdash) {
-              chart.copyProps(minChart);
-              minCharts.push(minChart);
-            }
-          })
-          localStorage["QDRCharts"] = angular.toJson(minCharts);
-        },
-        loadCharts: function() {
-          var charts = angular.fromJson(localStorage["QDRCharts"]);
-          if (charts) {
-            // get array of known ids
-            var nodeList = QDRService.nodeList().map(function(node) {
-              return node.id;
-            })
-            charts.forEach(function(chart) {
-              // if this chart is not in the current list of nodes, skip
-              if (nodeList.indexOf(chart.nodeId) >= 0) {
-                if (!angular.isDefined(chart.instance)) {
-                  chart.instance = ++instance;
-                }
-                if (chart.instance >= instance)
-                  instance = chart.instance + 1;
-                if (!chart.duration)
-                  chart.duration = 10;
-                if (chart.nodeList)
-                  chart.aggregate = true;
-                if (!chart.hdash)
-                  chart.hdash = false;
-                if (!chart.dashboard)
-                  chart.dashboard = false;
-                if (!chart.hdash && !chart.dashboard)
-                  chart.dashboard = true;
-                if (chart.hdash && chart.dashboard)
-                  chart.dashboard = false;
-                chart.forceCreate = true;
-                chart.use_instance = true;
-                var newChart = self.registerChart(chart); //chart.nodeId, chart.entity, chart.name, chart.attr, chart.interval, true, chart.aggregate);
-                newChart.dashboard = chart.dashboard;
-                newChart.hdash = chart.hdash;
-                newChart.hreq = false;
-                newChart.type = chart.type;
-                newChart.rateWindow = chart.rateWindow;
-                newChart.areaColor = chart.areaColor ? chart.areaColor : "#cbe7f3";
-                newChart.lineColor = chart.lineColor ? chart.lineColor : "#058dc7";
-                newChart.duration(chart.duration);
-                newChart.visibleDuration = chart.visibleDuration ? chart.visibleDuration : 10;
-                if (chart.userTitle)
-                  newChart.title(chart.userTitle);
-              }
-            })
-          }
-        },
-
-        AreaChart: function(chart) {
-          if (!chart)
-            return;
-
-          // if this is an aggregate chart, show it stacked
-          var stacked = chart.request().aggregate;
-          this.chart = chart; // reference to underlying chart
-          this.svgchart = null;
-          this.url = $location.absUrl();
-
-          // callback function. called by svgchart when binding data
-          // the variable 'this' refers to the svg and not the AreaChart,
-          // but since we are still in the scope of the AreaChart we have access to the passed in chart argument
-          this.chartData = function() {
-
-            var now = new Date();
-            var visibleDate = new Date(now.getTime() - chart.visibleDuration * 60 * 1000);
-            var data = chart.data();
-            var nodeList = QDRService.nodeIdList();
-
-            if (chart.type == "rate") {
-              var rateData = [];
-              var datalen = data.length;
-              k = 0; // inner loop optimization
-              for (var i = 0; i < datalen; ++i) {
-                var d = data[i];
-                if (d[0] >= visibleDate) {
-                  for (var j = k + 1; j < datalen; ++j) {
-                    var d1 = data[j];
-                    if (d1[0] - d[0] >= chart.rateWindow) { // rateWindow is the timespan to calculate rates
-                      var elapsed = Math.max((d1[0] - d[0]) / 1000, 1); // number of seconds that elapsed
-                      var rd = [d1[0], (d1[1] - d[1]) / elapsed]
-                      k = j; // start here next time
-                      // this is a stacked (aggregate) chart
-                      if (stacked) {
-                        var detail = [];
-                        nodeList.forEach(function(node, nodeIndex) {
-                          if (d1[2][nodeIndex] && d[2][nodeIndex])
-                            detail.push({
-                              node: QDRService.nameFromId(node),
-                              val: (d1[2][nodeIndex].val - d[2][nodeIndex].val) / elapsed
-                            })
-                        })
-                        rd.push(detail)
-                      }
-                      rateData.push(rd);
-                      break;
-                    }
-                  }
-                }
-              }
-              // we need at least a point to chart
-              if (rateData.length == 0) {
-                rateData[0] = [chart.data()[0][0], 0, [{
-                  node: '',
-                  val: 0
-                }]];
-              }
-              return rateData;
-            }
-            if (chart.visibleDuration != chart.duration()) {
-              return data.filter(function(d) {
-                return d[0] >= visibleDate
-              });
-            } else
-              return data;
-          }
-
-          this.zoom = function(id, zoom) {
-            if (this.svgchart) {
-              this.svgchart.attr("zoom", zoom)
-              d3.select('#' + id)
-                .data([this.chartData()])
-                .call(this.svgchart)
-            }
-          }
-
-          // called by the controller on the page that displays the chart
-          // called whenever the controller wants to redraw the chart
-          // note: the data is collected independently of how often the chart is redrawn
-          this.tick = function(id) {
-
-            // can't draw charts that don't have data yet
-            if (this.chart.data().length == 0) {
-              return;
-            }
-
-            // if we haven't created the svg yet
-            if (!this.svgchart) {
-
-              // make sure the dom element exists on the page
-              var div = angular.element('#' + id);
-              if (!div)
-                return;
-
-              var width = div.width();
-              var height = div.height();
-
-              // make sure the dom element has a size. otherwise we wouldn't see anything anyway
-              if (!width)
-                return;
-
-              var tooltipGenerator;
-              // stacked charts have a different tooltip
-              if (stacked) {
-                tooltipGenerator = function(d, color, format) {
-                  var html = "<table class='fo-table'><tbody><tr class='fo-title'>" +
-                    "<td align='center' colspan='2' nowrap>Time: " + d[0].toTimeString().substring(0, 8) + "</td></tr>"
-                  d[2].forEach(function(detail) {
-                    html += "<tr class='detail'><td align='right' nowrap>" + detail.node + "<div class='fo-table-legend' style='background-color: " + color(detail.node) + "'></div>" + "</td><td>" + format(detail.val) + "</td></tr>"
-                  })
-                  html += "</tbody></table>"
-                  return html;
-                }
-              } else {
-                tooltipGenerator = function(d, color, format) {
-                  var html = "<table class='fo-table'><tbody><tr class='fo-title'>" +
-                    "<td align='center'>Time</td><td align='center'>Value</td></tr><tr><td>" +
-                    d[0].toTimeString().substring(0, 8) +
-                    "</td><td>" +
-                    format(d[1]) +
-                    "</td></tr></tbody></table>"
-                  return html;
-                }
-              }
-              // create and initialize the chart
-              this.svgchart = self.timeSeriesStackedChart(id, width, height,
-                  QDRService.humanify(this.chart.attr()),
-                  this.chart.name(),
-                  QDRService.nameFromId(this.chart.nodeId()),
-                  this.chart.entity(),
-                  stacked,
-                  this.chart.visibleDuration)
-                .tooltipGenerator(tooltipGenerator);
-
-            }
-            // in case the chart properties have changed, set the new props
-            this.svgchart
-              .attr("type", this.chart.type)
-              .attr("areaColor", this.chart.areaColor)
-              .attr("lineColor", this.chart.lineColor)
-              .attr("url", this.url)
-              .attr("title", this.chart.userTitle);
-
-            // bind the new data and update the chart
-            d3.select('#' + id) // the div id on the page/dialog
-              .data([this.chartData()])
-              .call(this.svgchart); // the charting function
-          }
-        },
-
-        timeSeriesStackedChart: function(id, width, height, attrName, name, node, entity, stacked, visibleDuration) {
-          var margin = {
-              top: 20,
-              right: 18,
-              bottom: 10,
-              left: 15
-            }
-            // attrs that can be changed after the chart is created by using
-            // chart.attr(<attrname>, <attrvalue>);
-          var attrs = {
-            attrName: attrName, // like Deliveries to Container. Put at top of chart
-            name: name, // like router.address/qdrhello  Put at bottom of chart with node
-            node: node, // put at bottom of chart with name
-            entity: entity, // like .router.address  Not used atm
-            title: "", // user title overrides the node and name at the bottom of the chart
-            url: "", // needed to reference filters and clip because of angular's location service
-            type: "value", // value or rate
-            areaColor: "", // can be set for non-stacked charts
-            lineColor: "", // can be set for non-stacked charts
-            zoom: false, // should the y-axis range start at 0 or the min data value
-            visibleDuration: visibleDuration
-          }
-          var width = width - margin.left - margin.right,
-            height = height - margin.top - margin.bottom,
-            yAxisTransitionDuration = 0
-
-          var x = d3.time.scale()
-          var y = d3.scale.linear()
-            .rangeRound([height, 0]);
-          // The x-accessor for the path generator; xScale * xValue.
-          var X = function(d) {
-              return x(d[0])
-            }
-            // The x-accessor for the path generator; yScale * yValue.
-          var Y = function Y(d) {
-            return y(d[1])
-          }
-
-          var xAxis = d3.svg.axis().scale(x).orient("bottom")
-            .outerTickSize(6)
-            .innerTickSize(-(height - margin.top - margin.bottom))
-            .tickPadding(2)
-            .ticks(d3.time.minutes, 2)
-          var yAxis = d3.svg.axis().scale(y).orient("right")
-            .outerTickSize(8)
-            .innerTickSize(-(width - margin.left - margin.right))
-            .tickPadding(10)
-            .ticks(3)
-            .tickFormat(function(d) {
-              return formatValue(d)
-            })
-
-          var tooltipGenerator = function(d, color, format) {
-            return ""
-          }; // should be overridden to set an appropriate tooltip
-          var formatValue = d3.format(".2s");
-          var formatPrecise = d3.format(",");
-          var bisectDate = d3.bisector(function(d) {
-            return d[0];
-          }).left;
-          var line = d3.svg.line();
-
-          var stack = d3.layout.stack()
-            .offset("zero")
-            .values(function(d) {
-              return d.values;
-            })
-            .x(function(d) {
-              return x(d.date);
-            })
-            .y(function(d) {
-              return d.value;
-            });
-
-          var area = d3.svg.area()
-          if (stacked) {
-            area.interpolate("cardinal")
-              .x(function(d) {
-                return x(d.date);
-              })
-              .y0(function(d) {
-                return y(d.y0);
-              })
-              .y1(function(d) {
-                return y(d.y0 + d.y);
-              });
-          } else {
-            area.interpolate("basis").x(X).y1(Y)
-            line.x(X).y(Y)
-          }
-          var color = d3.scale.category20();
-
-          var sv = d3.select("#" + id).append("svg")
-            .attr("width", width + margin.left + margin.right)
-            .attr("height", height + margin.top + margin.bottom)
-          var svg = sv
-            .append("g")
-            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
-
-          sv.append("linearGradient")
-            .attr("id", id) //"temperature-gradient")
-            .attr("gradientUnits", "userSpaceOnUse")
-            .attr("x1", 0).attr("y1", height * .5)
-            .attr("x2", 0).attr("y2", height * 1.2)
-            .selectAll("stop")
-            .data([{
-              offset: "0%",
-              opacity: 1
-            }, {
-              offset: "100%",
-              opacity: 0
-            }])
-            .enter().append("stop")
-            .attr("offset", function(d) {
-              return d.offset;
-            })
-            .attr("stop-opacity", function(d) {
-              return d.opacity;
-            })
-            .attr("stop-color", function(d) {
-              return "#cbe7f3"
-            });
-          /*
-                      var clip = svg.append("defs").append("svg:clipPath")
-                        .attr("id", "clip")
-                        .append("svg:rect")
-                        .attr("id", "clip-rect")
-                        .attr("x", "0")
-                        .attr("y", "0")
-                        .attr("width", width)
-                        .attr("height", height);
-          */
-          // we want all our areas to appear before the axiis
-          svg.append("g")
-            .attr("class", "section-container")
-
-          svg.append("g")
-            .attr("class", "x axis")
-
-          svg.append("g")
-            .attr("class", "y axis")
-
-          svg.append("text").attr("class", "title")
-            .attr("x", (width / 2) - (margin.left + margin.right) / 2)
-            .attr("y", 0 - (margin.top / 2))
-            .attr("text-anchor", "middle")
-            .text(attrs.attrName);
-
-          svg.append("text").attr("class", "legend")
-            .attr("x", (width / 2) - (margin.left + margin.right) / 2)
-            .attr("y", height + (margin.bottom / 2))
-            .attr("text-anchor", "middle")
-            .text(!stacked ? attrs.node + " " + attrs.name : attrs.name);
-
-          var focus = sv.append("g")
-            .attr("class", "focus")
-            .style("display", "none");
-
-          focus.append("circle")
-            .attr("r", 4.5);
-
-          var focusg = focus.append("g");
-          focusg.append("rect")
-            .attr("class", "mo-guide y")
-            .attr("width", 1)
-            .attr("height", height - (margin.top + margin.bottom));
-          focusg.append("rect")
-            .attr("class", "mo-guide x")
-            .attr("width", width - (margin.left + margin.right))
-            .attr("height", 1);
-          focus.append("foreignObject")
-            .attr('class', 'svg-tooltip')
-            .append("xhtml:span");
-          /*
-                  var transition = d3.select({}).transition()
-                      .duration(2000)
-                      .ease("linear");
-          */
-          function chart(selection) {
-            selection.each(function(data) {
-
-              var seriesArr = []
-              if (stacked) {
-                var detailNames = data[0][2].map(function(detail) {
-                  return detail.node
-                })
-                var revNames = angular.copy(detailNames).reverse();
-                color.domain(revNames);
-
-                var series = {};
-                detailNames.forEach(function(name) {
-                  series[name] = {
-                    name: name,
-                    values: []
-                  };
-                  seriesArr.unshift(series[name]); // insert at beginning
-                });
-
-                data.forEach(function(d) {
-                  detailNames.map(function(name, i) {
-                    series[name].values.push({
-                      date: d[0],
-                      value: d[2][i] ? d[2][i].val : 0
-                    });
-                  });
-                });
-
-                // this decorates seriesArr with x,y,and y0 properties
-                stack(seriesArr);
-              }
-
-              var extent = d3.extent(data, function(d) {
-                return d[0];
-              });
-              //var points = data.length;
-              //var futureDate = new Date(data[points-1][0].getTime() - attrs.visibleDuration * 60 * 1000);
-              //extent = [futureDate, data[points-1][0]]
-              x.domain(extent)
-                .range([0, width - margin.left - margin.right]);
-
-              // Update the y-scale.
-              var min = attrs.zoom ? 0 : d3.min(data, function(d) {
-                return d[1]
-              }) * .99;
-              var max = d3.max(data, function(d) {
-                return d[1]
-              }) * 1.01;
-              var mean = d3.mean(data, function(d) {
-                return d[1]
-              });
-              //max = max * 1.01;
-              var diff = (max - min);
-              if (diff == 0) {
-                max = max + 1;
-                diff = 1;
-              }
-              var ratio = mean != 0 ? diff / mean : 1;
-              if (ratio < .05)
-                formatValue = d3.format(".3s")
-
-              if (stacked) {
-                y.domain([min, max])
-                  .range([height - margin.top - margin.bottom, 0]);
-              } else {
-                y
-                  .domain([min, max])
-                  .range([height - margin.top - margin.bottom, 0]);
-              }
-              if (attrs.type == "rate") {
-                area.interpolate("linear"); // rate charts look better smoothed, but the tooltop is in the wrong place
-                line.interpolate("linear");
-//                area.interpolate("basis"); // rate charts look better smoothed
-//                line.interpolate("basis");
-              } else {
-                area.interpolate("linear"); // don't smooth value charts
-                line.interpolate("linear");
-              }
-
-              // adjust the xaxis based on the range of x values (domain)
-              var timeSpan = (extent[1] - extent[0]) / (1000 * 60); // number of minutes
-              if (timeSpan < 1.5)
-                xAxis.ticks(d3.time.seconds, 10);
-              else if (timeSpan < 3)
-                xAxis.ticks(d3.time.seconds, 30);
-              else if (timeSpan < 8)
-                xAxis.ticks(d3.time.minutes, 1);
-              else
-                xAxis.ticks(d3.time.minutes, 2);
-
-              // adjust the number of yaxis ticks based on the range of y values
-              if (formatValue(min) === formatValue(max))
-                yAxis.ticks(2);
-
-              var container = svg.select('.section-container');
-              container.selectAll('.series').remove();
-              if (stacked) {
-                y.domain([Math.min(min, 0), d3.max(seriesArr, function(c) {
-                  return d3.max(c.values, function(d) {
-                    return d.y0 + d.y;
-                  });
-                })]);
-
-                // creates a .series g path for each section in the detail
-                // since we don't get more sections this selection is only run once
-                var series = container.selectAll(".series")
-                  .data(seriesArr)
-
-                series.enter().append("g")
-                  .attr("class", "series")
-                  .append("path")
-                  .attr("class", "streamPath")
-                  .style("fill", function(d) {
-                    return color(d.name);
-                  })
-                  .style("stroke", "grey");
-
-                series.exit().remove()
-
-                // each time the data is updated, update each section
-                container.selectAll(".series .streamPath").data(seriesArr)
-                  .attr("d", function(d) {
-                    return area(d.values);
-                  })
-              } else {
-                var series = container.selectAll(".series")
-                  .data([data], function(d) {
-                    return d;
-                  })
-
-                var g = series.enter().append("g")
-                  .attr("class", "series")
-
-                g.append("path")
-                  .attr("class", "area")
-                  .style("fill", "url(" + attrs.url + "#" + id + ") " + attrs.areaColor) //temperature-gradient)")
-                  .attr("d", area.y0(y.range()[0]))
-                  .attr("transform", null);
-
-                g.append("path")
-                  .attr("class", "line")
-                  .style("stroke", attrs.lineColor)
-                  .attr("d", line)
-                  /*
-                  debugger;
-                              g.transition()
-                                .duration(2000)
-                                              .attr("transform", "translate(-4)");
-                  */
-                series.exit().remove()
-
-                sv.selectAll("stop")
-                  .attr("stop-color", attrs.areaColor)
-
-              }
-              // Update the x-axis.
-              svg.select(".x.axis")
-                .attr("transform", "translate(0," + (height - margin.top - margin.bottom + 1) + ")")
-                .call(xAxis);
-
-              svg.select(".y.axis")
-                .transition().duration(yAxisTransitionDuration) // animate the y axis
-                .attr("transform", "translate(" + (width - margin.right - margin.left) + ",0)")
-                .call(yAxis);
-              yAxisTransitionDuration = 1000 // only do a transition after the chart is 1st drawn
-
-              // TODO: fix this
-              // need to recreate this every update... not sure why
-              var overlay = sv.select(".overlay");
-              if (!overlay.empty())
-                overlay.remove();
-              sv.append("rect")
-                .attr("class", "overlay")
-                .attr("width", width)
-                .attr("height", height)
-                .on("mouseover", function() {
-                  focus.style("display", null)
-                })
-                .on("mouseout", function() {
-                  focus.style("display", "none")
-                })
-                .on("mousemove", mousemove)
-
-              function mousemove() {
-                var x0 = x.invert(d3.mouse(this)[0] - margin.left);
-                var i = bisectDate(data, x0, 1);
-                if (i < data.length && i > 0) {
-                  var d0 = data[i - 1];
-                  var d1 = data[i];
-                  // set d to the data that is closest to the mouse position
-                  var d = x0 - d0[0] > d1[0] - x0 ? d1 : d0;
-                  focus.attr("transform", "translate(" + (x(d[0]) + margin.left) + "," + (y(d[1]) + margin.top) + ")");
-
-                  var tipFormat = formatPrecise;
-                  if (attrs.type === "rate")
-                    tipFormat = d3.format(".2n")
-                    // set the tooltip html and position it
-                  focus.select('.svg-tooltip span')
-                    .html(tooltipGenerator(d, color, tipFormat))
-
-                  var foBounds = focus.select('table')[0][0].getBoundingClientRect();
-                  var mx = x(d[0]); // mouse x
-                  var my = y(d[1]); // mouse y
-
-                  // perfer to put the tooltip in the nw corner relative to the focus circle
-                  var foy = -foBounds.height;
-                  var fox = -foBounds.width;
-                  // off the left side
-                  if (mx - foBounds.width - margin.left < 0)
-                    fox = 0;
-                  // above the top
-                  if (my - foBounds.height - margin.top < 0)
-                    foy = 0;
-                  // won't fit above or below, just put it at bottom
-                  if (my + foBounds.height > height)
-                    foy = -(foBounds.height - (height - my));
-
-                  focus.select('.svg-tooltip')
-                    .attr('x', fox).attr('y', foy);
-
-                  // position the guide lines
-                  focus.select(".mo-guide.y")
-                    .attr("y", -my);
-                  focus.select(".mo-guide.x")
-                    .attr("x", -mx);
-
-                } else {
-                  focus.attr("transform", "translate(-10,-10)");
-                }
-              }
-
-            })
-          }
-          chart.attr = function(attrName, value) {
-            if (arguments.length < 2)
-              return arguments.length == 1 ? attrs[attrName] : chart;
-            if (angular.isDefined(attrs[attrName]))
-              attrs[attrName] = value;
-            return chart;
-          }
-          chart.tooltipGenerator = function(_) {
-            tooltipGenerator = _;
-            return chart;
-          }
-          return chart;
-        }
-      }
-      return self;
-    }
-  ]);
-
-  return QDR;
-}(QDR || {}));
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrCharts.js b/console/hawtio/src/main/webapp/plugin/js/qdrCharts.js
deleted file mode 100644
index 30a9b99..0000000
--- a/console/hawtio/src/main/webapp/plugin/js/qdrCharts.js
+++ /dev/null
@@ -1,331 +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.
-*/
-/**
- * @module QDR
- */
-var QDR = (function (QDR) {
-
-  /**
-   * @method ChartsController
-   *
-   * Controller that handles displaying a chart on the hawtio dashboard page. Only one chart is displayed per instance of this
-   * page
-   */
-  QDR.module.controller("QDR.ChartsController", function($scope, QDRService, QDRChartService, $dialog, $location, $routeParams) {
-
-	var updateTimer = null;
-
-	if (!QDRService.connected && !$routeParams.chid) {
-		// we are not connected. we probably got here from a bookmark or manual page reload
-		QDRService.redirectWhenConnected("charts");
-		return;
-	}
-	// we are currently connected. setup a handler to get notified if we are ever disconnected
-	QDRService.addDisconnectAction( function () {
-		QDRService.redirectWhenConnected("charts")
-		$scope.$apply();
-	})
-
-
-    $scope.svgCharts = [];
-    // create an svg object for each chart
-    QDRChartService.charts.some(function (chart) {
-		// we are generating a chart for the hawtio dashboard
-		if ( $routeParams.chid == chart.id()) {
-	        var svgChart = new QDRChartService.AreaChart(chart)
-	        svgChart.zoomed = false;
-	        $scope.svgCharts.push(svgChart);
-
-			// a hawtio dashboard has requested to view this chart. mark the chart so the request to get the data is made
-			if ($routeParams.chid && chart.hdash) {
-				chart.hreq = true;
-			}
-			return true;
-		}
-    })
-
-    // redraw the chart every update period
-	// this is a $scope function because it is called from the dialog
-    var updateCharts = function () {
-        $scope.svgCharts.forEach(function (svgChart) {
-            svgChart.tick(svgChart.chart.id()); // on this page we are using the chart.id() as the div id in which to render the chart
-        })
-		var updateRate = localStorage['updateRate'] ?  localStorage['updateRate'] : 5000;
-		if (updateTimer) {
-			clearTimeout(updateTimer)
-		}
-        updateTimer = setTimeout(updateCharts, updateRate);
-    }
-
-	// we are showing a chart for the hawtio dashboard page, but we are not logged in
-	// set this to cause a "need to login" prompt on the dashboard
-	$scope.dashLogin = !QDRService.connected;
-	// the link that the above login prompt will display
-	$scope.loginHref = QDR.pluginName + "/connect";
-
-	// called by ng-init in the html when the page is loaded
-	$scope.chartsLoaded = function () {
-        $scope.svgCharts.forEach(function (svgChart) {
-            QDRChartService.sendChartRequest(svgChart.chart.request(), true);
-        })
-        if (updateTimer)
-            clearTimeout(updateTimer)
-		updateTimer = setTimeout(updateCharts, 100);
-	}
-
-	$scope.zoomChart = function (chart) {
-		chart.zoomed = !chart.zoomed;
-		chart.zoom(chart.chart.id(), chart.zoomed);
-	}
-    $scope.editChart = function (chart) {
-        doDialog("chart-config-template.html", chart.chart);
-    };
-
-    $scope.delChart = function (chart) {
-        QDRChartService.unRegisterChart(chart.chart);
-        // remove from svgCharts
-        $scope.svgCharts.forEach(function (svgChart, i) {
-            if (svgChart === chart) {
-                delete $scope.svgCharts.splice(i, 1);
-            }
-        })
-    };
-
-    // called from dialog when we want to clone the dialog chart
-    // the chart argument here is a QDRChartService chart
-    $scope.addChart = function (chart) {
-        $scope.svgCharts.push(new QDRChartService.AreaChart(chart));
-    };
-
-	$scope.$on("removedFromDashboard", function (event) {
-		QDRChartService.unRegisterChart($scope.svgCharts[0].chart)
-	})
-    $scope.$on("$destroy", function( event) {
-        if (updateTimer) {
-            clearTimeout(updateTimer);
-            updateTimer = null;
-        }
-		if ($scope.svgCharts.length) {
-			//if ($scope.svgCharts[0].chart)
-			//	$scope.svgCharts[0].chart.hreq = false; // stops the chart service from making requests for this chart
-	        for (var i=$scope.svgCharts.length-1; i>=0; --i) {
-	            delete $scope.svgCharts.splice(i, 1);
-	        }
-		}
-    });
-
-	// clicked on add to dashboard
-	$scope.addHChart = function (chart) {
-        QDRChartService.addHDash(chart.chart);
-	}
-
-	// href that is generated when the page loads
-	$scope.addToDashboardLink = function (chart) {
-		var href = "#" + $location.path();
-		var size = angular.toJson({
-                size_x: 2,
-                size_y: 2
-              });
-
-		var params = angular.toJson({chid: chart.chart.id()});
-        var title = "Dispatch Router";
-	    return "/hawtio/#/dashboard/add?tab=dashboard" +
-	          "&href=" + encodeURIComponent(href) +
-	          "&routeParams=" + encodeURIComponent(params) +
-	          "&title=" + encodeURIComponent(title) +
-	          "&size=" + encodeURIComponent(size);
-    };
-
-    function doDialog(template, chart) {
-
-	    $dialog.dialog({
-			backdrop: true,
-			keyboard: true,
-			backdropClick: true,
-			templateUrl: template,
-			controller: "QDR.ChartDialogController",
-			resolve: {
-				chart: function() {
-					return chart;
-				},
-				updateTick: function () {
-					return updateCharts;
-				}
-			}
-	    }).open();
-    };
-
-  });
-
-	// the edit chart properties dialog
-  QDR.module.controller("QDR.ChartDialogController", function($scope, QDRChartService, $location, dialog, $rootScope, chart, updateTick) {
-
-		UI.colors[0] = "#cbe7f3"
-		UI.colors[1] = "#058dc7"
-		UI.colors[UI.colors.length-1] = "#FFFFFF"
-
-        var dialogSvgChart = null;
-        $scope.svgDivId = "dialogChart";    // the div id for the svg chart
-
-	var updateTimer = null;
-        $scope.chart = chart;  // the underlying chart object from the dashboard
-        $scope.dialogChart = $scope.chart.copy(); // the chart object for this dialog
-        $scope.userTitle = $scope.chart.title();
-
-        $scope.$watch('userTitle', function(newValue, oldValue) {
-            if (newValue !== oldValue) {
-                $scope.dialogChart.title(newValue);
-                dialogSvgChart.tick($scope.svgDivId);
-            }
-        })
-		$scope.$watch("dialogChart.areaColor", function (newValue, oldValue) {
-			if (newValue !== oldValue) {
-				if (dialogSvgChart) {
-                    dialogSvgChart.tick($scope.svgDivId);
-                }
-			}
-		})
-		$scope.$watch("dialogChart.lineColor", function (newValue, oldValue) {
-			if (newValue !== oldValue) {
-				if (dialogSvgChart)
-                    dialogSvgChart.tick($scope.svgDivId);
-			}
-		})
-		$scope.$watch("dialogChart.type", function (newValue, oldValue) {
-			if (newValue !== oldValue) {
-				if (dialogSvgChart)
-                    dialogSvgChart.tick($scope.svgDivId);
-			}
-		})
-
-        // the stored rateWindow is in milliseconds, but the slider is in seconds
-        $scope.rateWindow = $scope.chart.rateWindow / 1000;
-
-		var cleanup = function () {
-			if (updateTimer) {
-				clearTimeout(updateTimer);
-				updateTimer = null;
-			}
-			QDRChartService.unRegisterChart($scope.dialogChart);     // remove the chart
-		}
-		$scope.okClick = function () {
-		    cleanup();
-	            dialog.close();
-	    };
-
-		var initRateSlider = function () {
-			if (document.getElementById('rateSlider')) {
-				$( "#rateSlider" ).slider({
-				      value: $scope.rateWindow,
-				      min: 1,
-				      max: 10,
-				      step: 1,
-				      slide: function( event, ui ) {
-						$scope.rateWindow = ui.value;
-						$scope.dialogChart.rateWindow = ui.value * 1000;
-						$scope.$apply();
-						if (dialogSvgChart)
-							dialogSvgChart.tick($scope.svgDivId);
-				      }
-				});
-
-			} else {
-				setTimeout(initRateSlider, 100)
-			}
-		}
-		initRateSlider();
-
-		var initDurationSlider = function () {
-			if (document.getElementById('durationSlider')) {
-				$( "#durationSlider" ).slider({
-				      value: $scope.dialogChart.visibleDuration,
-				      min: 1,
-				      max: 10,
-				      step: 1,
-				      slide: function( event, ui ) {
-						$scope.visibleDuration = $scope.dialogChart.visibleDuration = ui.value;
-						$scope.$apply();
-						if (dialogSvgChart)
-							dialogSvgChart.tick($scope.svgDivId);
-				      }
-				});
-
-			} else {
-				setTimeout(initDurationSlider, 100)
-			}
-		}
-		initDurationSlider();
-
-        // handle the Apply button click
-        // update the dashboard chart's properties
-        $scope.apply = function () {
-            $scope.chart.areaColor = $scope.dialogChart.areaColor;
-            $scope.chart.lineColor = $scope.dialogChart.lineColor;
-            $scope.chart.type = $scope.dialogChart.type;
-            $scope.chart.rateWindow = $scope.rateWindow * 1000;
-            $scope.chart.title($scope.dialogChart.title());
-            $scope.chart.visibleDuration = $scope.dialogChart.visibleDuration;
-            QDRChartService.saveCharts();
-			if (typeof updateTick === "function")
-				updateTick();
-        }
-
-        // update the chart on the popup dialog
-        var updateDialogChart = function () {
-            // draw the chart using the current data
-            if (dialogSvgChart) {
-                dialogSvgChart.tick($scope.svgDivId);
-			}
-            // draw the chart again in 1 second
-			var updateRate = localStorage['updateRate'] ? localStorage['updateRate'] : 5000;
-			if (updateTimer)
-				clearTimeout(updateTimer);
-            updateTimer = setTimeout(updateDialogChart, updateRate);
-        }
-
-        var showChart = function () {
-            // ensure the div for our chart is loaded in the dom
-            var div = angular.element("#dialogChart");
-            if (!div.width()) {
-                setTimeout(showChart, 100);
-                return;
-            }
-            dialogSvgChart = new QDRChartService.AreaChart($scope.dialogChart);
-			$('input[name=lineColor]').val($scope.dialogChart.lineColor);
-			$('input[name=areaColor]').val($scope.dialogChart.areaColor);
-			$('input[name=areaColor]').on('input', function (e) {
-				$scope.dialogChart.areaColor = $(this).val();
-                updateDialogChart()
-			})
-			$('input[name=lineColor]').on('input', function (e) {
-				$scope.dialogChart.lineColor = $(this).val();
-                updateDialogChart()
-			})
-			if (updateTimer)
-				clearTimeout(updateTimer);
-            updateDialogChart();
-        }
-        showChart();
-
-
-  });
-
-  return QDR;
-
-}(QDR || {}));
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrList.js b/console/hawtio/src/main/webapp/plugin/js/qdrList.js
deleted file mode 100644
index b39c37f..0000000
--- a/console/hawtio/src/main/webapp/plugin/js/qdrList.js
+++ /dev/null
@@ -1,804 +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.
-*/
-/**
- * @module QDR
- */
-var QDR = (function(QDR) {
-
-  /**
-   * @method ListController
-   * @param $scope
-   * @param QDRService
-   *
-   * Controller for the main interface
-   */
-  QDR.module.controller("QDR.ListController", ['$scope', '$location', '$dialog', '$filter', '$timeout', 'QDRService', 'QDRChartService',
-    function ($scope, $location, $dialog, $filter, $timeout, QDRService, QDRChartService) {
-
-    var updateIntervalHandle = undefined;
-    var updateInterval = 5000;
-    var ListExpandedKey = "QDRListExpanded";
-    $scope.details = {};
-
-    $scope.tmplListTree = QDR.templatePath + 'tmplListTree.html';
-    $scope.selectedEntity = localStorage['QDRSelectedEntity'] || "address";
-    $scope.selectedNode = localStorage['QDRSelectedNode'];
-    $scope.selectedNodeId = localStorage['QDRSelectedNodeId'];
-    $scope.selectedRecordName = localStorage['QDRSelectedRecordName'];
-    $scope.nodes = []
-    $scope.currentNode = undefined;
-    $scope.modes = [
-      {
-        content: '<a><i class="icon-list"></i> Attributes</a>',
-        id: 'attributes',
-        op: 'READ',
-        title: "View router attributes",
-        isValid: function () { return true; }
-      },
-      {
-        content: '<a><i class="icon-edit"></i> Update</a>',
-        id: 'operations',
-        op: 'UPDATE',
-        title: "Update this attribute",
-        isValid: function () {
-          //QDR.log.debug("isValid UPDAATE? " + this.op)
-          //console.dump($scope.operations)
-          return $scope.operations.indexOf(this.op) > -1
-        }
-      },
-      {
-        content: '<a><i class="icon-plus"></i> Create</a>',
-        id: 'operations',
-        op: 'CREATE',
-        title: "Create a new attribute",
-        isValid: function () { return $scope.operations.indexOf(this.op) > -1 }
-      },
-      {
-        content: '<a><i class="icon-remove"></i> Delete</a>',
-        id: 'delete',
-        op: 'DELETE',
-        title: "Delete",
-        isValid: function () { return $scope.operations.indexOf(this.op) > -1 }
-      },
-      {
-        content: '<a><i class="icon-eye-open"></i> Fetch</a>',
-        id: 'log',
-        op: 'GET-LOG',
-        title: "Fetch recent log entries",
-        isValid: function () { return ($scope.selectedEntity === 'log') }
-      }
-    ];
-    $scope.operations = []
-      $scope.currentMode = $scope.modes[0];
-      $scope.isModeSelected = function (mode) {
-      return mode === $scope.currentMode;
-    }
-    $scope.fetchingLog = false;
-    $scope.selectMode = function (mode) {
-      $scope.currentMode = mode;
-      if (mode.id === 'log') {
-        $scope.logResults = [];
-        $scope.fetchingLog = true;
-        var entity; // undefined since it is not supported in the GET-LOG call
-        QDRService.sendMethod($scope.currentNode.id, entity, {}, $scope.currentMode.op, {}, function (nodeName, entity, response, context) {
-          $scope.fetchingLog = false;
-          var statusCode = context.message.application_properties.statusCode;
-          if (statusCode < 200 || statusCode >= 300) {
-            Core.notification('error', context.message.statusDescription);
-            QDR.log.info('Error ' + context.message.statusDescription)
-            return;
-          }
-          $scope.logResults = response.filter( function (entry) {
-            return entry[0] === $scope.detailsObject.module
-          }).sort( function (a, b) {
-            return b[5] - a[5]
-          }).map( function (entry) {
-            return {
-              type: entry[1],
-              message: entry[2],
-              source: entry[3],
-              line: entry[4],
-              time: Date(entry[5]).toString()
-            }
-          })
-          $scope.$apply();
-        })
-      }
-    }
-    $scope.isValid = function (mode) {
-      return mode.isValid()
-    }
-
-    $scope.expandAll = function () {
-      $("#entityTree").dynatree("getRoot").visit(function(node){
-                node.expand(true);
-            });
-    }
-    $scope.contractAll = function () {
-      $("#entityTree").dynatree("getRoot").visit(function(node){
-                node.expand(false);
-            });
-    }
-
-    if (!QDRService.connected) {
-      // we are not connected. we probably got here from a bookmark or manual page reload
-      QDRService.redirectWhenConnected("list");
-      return;
-    }
-    // we are currently connected. setup a handler to get notified if we are ever disconnected
-    var onDisconnect = function () {
-      $timeout(function () { QDRService.redirectWhenConnected("list") })
-    }
-    QDRService.addDisconnectAction( onDisconnect )
-
-    $scope.nodes = []
-    var excludedEntities = ["management", "org.amqp.management", "operationalEntity", "entity", "configurationEntity", "dummy", "console"];
-    var aggregateEntities = ["router.address"];
-    var classOverrides = {
-      "connection": function (row, nodeId) {
-        var isConsole = QDRService.isAConsole (row.properties.value, row.identity.value, row.role.value, nodeId)
-        return isConsole ? "console" : row.role.value === "inter-router" ? "inter-router" : "external";
-      },
-      "router.link": function (row, nodeId) {
-        var link = {nodeId: nodeId, connectionId: row.connectionId.value}
-        var isConsole = QDRService.isConsoleLink(link)
-        return isConsole ? "console" : row.linkType.value;
-      },
-      "router.address": function (row) {
-        var identity = QDRService.identity_clean(row.identity.value)
-        var address = QDRService.addr_text(identity)
-        var cls = QDRService.addr_class(identity)
-        if (address === "$management")
-          cls = "internal " + cls
-        return cls
-      }
-    }
-
-    var lookupOperations = function () {
-      var ops = QDRService.schema.entityTypes[$scope.selectedEntity].operations.filter( function (op) { return op !== 'READ'});
-      $scope.operation = ops.length ? ops[0] : "";
-      return ops;
-    }
-
-    var entityTreeChildren = [];
-    var expandedList = angular.fromJson(localStorage[ListExpandedKey]) || [];
-    var onTreeNodeExpanded = function (expanded, node) {
-      // save the list of entities that are expanded
-      var tree = $("#entityTree").dynatree("getTree");
-      var list = [];
-      tree.visit( function (tnode) {
-        if (tnode.isExpanded()) {
-          list.push(tnode.data.key)
-        }
-      })
-      localStorage[ListExpandedKey] = JSON.stringify(list)
-
-      if (expanded)
-        onTreeSelected(node);
-    }
-    // a tree node was selected
-    var onTreeSelected = function (selectedNode) {
-      $timeout( function () {
-        if ($scope.currentMode.id === 'operations')
-          $scope.currentMode = $scope.modes[0];
-        else if ($scope.currentMode.id === 'log')
-          $scope.selectMode($scope.currentMode)
-        else if ($scope.currentMode.id === 'delete') {
-          // clicked on a tree node while on the delete screen -> switch to attribute screen
-          $scope.currentMode = $scope.modes[0];
-        }
-        if (selectedNode.data.typeName === "entity") {
-          $scope.selectedEntity = selectedNode.data.key;
-          $scope.operations = lookupOperations()
-        } else if (selectedNode.data.typeName === 'attribute') {
-          $scope.selectedEntity = selectedNode.parent.data.key;
-          $scope.operations = lookupOperations()
-          $scope.selectedRecordName = selectedNode.data.key;
-          updateDetails(selectedNode.data.details);   // update the table on the right
-          $("#entityTree").dynatree("getRoot").visit(function(node){
-             node.select(false);
-          });
-          selectedNode.select();
-        }
-      })
-    }
-
-    // fill in an empty results recoord based on the entities schema
-    var fromSchema = function (entityName) {
-      var row = {}
-      var schemaEntity = QDRService.schema.entityTypes[entityName]
-      for (attr in schemaEntity.attributes) {
-        var entity = schemaEntity.attributes[attr]
-        var value = ""
-        if (angular.isDefined(entity['default']))
-          value = entity['default']
-        row[attr] = {
-          value: value,
-          type: entity.type,
-          graph: false,
-          title: entity.description,
-          aggregate: false,
-          aggregateTip: '',
-          'default': entity['default']
-        }
-      }
-      return row;
-    }
-    $scope.hasCreate = function () {
-      var schemaEntity = QDRService.schema.entityTypes[$scope.selectedEntity]
-      return (schemaEntity.operations.indexOf("CREATE") > -1)
-    }
-
-    var stopUpdating = function () {
-      if (angular.isDefined(updateIntervalHandle)) {
-        clearInterval(updateIntervalHandle);
-      }
-      updateIntervalHandle = undefined;
-    }
-
-    // the data for the selected entity is available, populate the tree
-    var updateEntityChildren = function (entity, tableRows, expand) {
-      var tree = $("#entityTree").dynatree("getTree");
-      if (!tree.getNodeByKey) {
-        return stopUpdating()
-      }
-      var node = tree.getNodeByKey(entity)
-      var updatedDetails = false;
-      var scrollTreeDiv = $('.qdr-attributes.pane.left .pane-viewport')
-      var scrollTop = scrollTreeDiv.scrollTop();
-      node.removeChildren();
-      if (tableRows.length == 0) {
-          node.addChild({
-          addClass:   "no-data",
-              typeName:   "none",
-              title:      "no data",
-          key:        node.data.key + ".1"
-          })
-          if (expand) {
-              updateDetails(fromSchema(entity));
-                 $scope.selectedRecordName = entity;
-        }
-      } else {
-        tableRows.forEach( function (row) {
-          var addClass = entity;
-          if (classOverrides[entity]) {
-            addClass += " " + classOverrides[entity](row, $scope.currentNode.id);
-          }
-          var child = {
-                        typeName:   "attribute",
-                        addClass:   addClass,
-                        tooltip:    addClass,
-                        key:        row.name.value,
-                        title:      row.name.value,
-                        details:    row
-                    }
-          if (row.name.value === $scope.selectedRecordName) {
-            if (expand)
-              updateDetails(row); // update the table on the right
-            child.select = true;
-            updatedDetails = true;
-          }
-          node.addChild(child)
-        })
-      }
-      // if the selectedRecordName was not found, select the 1st one
-      if (expand && !updatedDetails && tableRows.length > 0) {
-        var row = tableRows[0];
-        $scope.selectedRecordName = row.name.value;
-        if (tree.getNodeByKey) {
-          var node = tree.getNodeByKey($scope.selectedRecordName);
-          node.select(true);
-        }
-        updateDetails(row)  // update the table on the right
-      }
-      scrollTreeDiv.scrollTop(scrollTop)
-      $('.dynatree-title').each( function (idx) {
-        var unsafe = $(this).html()
-        $(this).html(unsafe.replace(/</g, "&lt;").replace(/>/g, "&gt;"))
-      })
-
-    }
-
-    var schemaProps = function (entityName, key, currentNode) {
-         var typeMap = {integer: 'number', string: 'text', path: 'text', boolean: 'boolean', map: 'textarea'};
-
-      var entity = QDRService.schema.entityTypes[entityName]
-      var value = entity.attributes[key]
-      // skip identity and depricated fields
-      if (!value)
-        return {input: 'input', type: 'disabled', required: false, selected: "", rawtype: 'string', disabled: true, 'default': ''}
-      var description = value.description || ""
-      var val = value['default'];
-      var disabled = (key == 'identity' || description.startsWith('Deprecated'))
-      // special cases
-      if (entityName == 'log' && key == 'module') {
-        return {input: 'input', type: 'disabled', required: false, selected: "", rawtype: 'string', disabled: true, 'default': ''}
-      }
-      if (entityName === 'linkRoutePattern' && key === 'connector') {
-        // turn input into a select. the values will be populated later
-        value.type = []
-        // find all the connector names and populate the select
-        QDRService.fetchEntity(currentNode.id, '.connector', ['name'], function (nodeName, dotentity, response) {
-          if (!response.results)
-            return
-          $scope.detailFields.some( function (field) {
-            if (field.name === 'connector') {
-              field.rawtype = response.results.map (function (result) {return result[0]})
-              return true;
-            }
-          })
-        });
-      }
-      return {    name:       key,
-            humanName:  QDRService.humanify(key),
-                        description:value.description,
-                        type:       disabled ? 'disabled' : typeMap[value.type],
-                        rawtype:    value.type,
-                        input:      typeof value.type == 'string' ? value.type == 'boolean' ? 'boolean' : 'input'
-                                                                  : 'select',
-                        selected:   val ? val : undefined,
-                        'default':  value['default'],
-                        value:      val,
-                        required:   value.required,
-                        unique:     value.unique,
-                        disabled:   disabled
-            };
-    }
-    $scope.getAttributeValue = function (attribute) {
-      var value = attribute.attributeValue;
-      if ($scope.currentMode.op === "CREATE" && attribute.name === 'identity')
-        value = "<assigned by system>"
-      return value;
-    }
-
-    // update the table on the right
-    var updateDetails = function (row) {
-      var details = [];
-      $scope.detailsObject = {};
-      var attrs = Object.keys(row).sort();
-      attrs.forEach( function (attr) {
-        var changed = $scope.detailFields.filter(function (old) {
-          return (old.name === attr) ? old.graph && old.rawValue != row[attr].value : false;
-        })
-        var schemaEntity = schemaProps($scope.selectedEntity, attr, $scope.currentNode)
-        details.push( {
-          attributeName:  QDRService.humanify(attr),
-          attributeValue: attr === 'port' ? row[attr].value : QDRService.pretty(row[attr].value),
-          name:           attr,
-          changed:        changed.length,
-          rawValue:       row[attr].value,
-          graph:          row[attr].graph,
-          title:          row[attr].title,
-          aggregateValue: QDRService.pretty(row[attr].aggregate),
-          aggregateTip:   row[attr].aggregateTip,
-
-          input:          schemaEntity.input,
-          type:           schemaEntity.type,
-          required:       schemaEntity.required,
-          unique:         schemaEntity.unique,
-          selected:       schemaEntity.selected,
-          rawtype:        schemaEntity.rawtype,
-          disabled:       schemaEntity.disabled,
-          'default':      schemaEntity['default']
-        })
-        $scope.detailsObject[attr] = row[attr].value;
-      })
-      setTimeout(applyDetails, 1, details)
-    }
-
-    var applyDetails = function (details) {
-      $scope.detailFields = details;
-      aggregateColumn();
-      $scope.$apply();
-      // ng-grid bug? the entire table doesn't always draw unless a reflow is triggered;
-      $(window).trigger('resize');
-    }
-
-    var restartUpdate = function () {
-      stopUpdating();
-      updateTableData($scope.selectedEntity, true);
-      updateIntervalHandle = setInterval(updateExpandedEntities, updateInterval);
-    }
-    var updateExpandedEntities = function () {
-      var tree = $("#entityTree").dynatree("getTree");
-      if (tree.visit) {
-        tree.visit( function (node) {
-          if (node.isExpanded()) {
-            updateTableData(node.data.key, node.data.key === $scope.selectedEntity)
-          }
-        })
-      } else {
-        stopUpdating();
-      }
-    }
-
-    $scope.selectNode = function(node) {
-      $scope.selectedNode = node.name;
-      $scope.selectedNodeId = node.id;
-      setCurrentNode();
-      restartUpdate();
-    };
-    $scope.$watch('selectedEntity', function(newValue, oldValue) {
-      if (newValue !== oldValue) {
-        localStorage['QDRSelectedEntity'] = $scope.selectedEntity;
-        restartUpdate();
-        $scope.operations = lookupOperations()
-      }
-    })
-    $scope.$watch('selectedNode', function(newValue, oldValue) {
-        if (newValue !== oldValue) {
-        localStorage['QDRSelectedNode'] = $scope.selectedNode;
-        localStorage['QDRSelectedNodeId'] = $scope.selectedNodeId;
-      }
-    })
-    $scope.$watch('selectedRecordName', function(newValue, oldValue) {
-      if (newValue != oldValue) {
-        localStorage['QDRSelectedRecordName'] = $scope.selectedRecordName;
-      }
-    })
-
-    /* Called periodically to refresh the data on the page */
-    var updateTableData = function (entity, expand) {
-      if (!QDRService.connected) {
-        // we are no longer connected. bail back to the connect page
-        $location.path("/" + QDR.pluginName + "/connect")
-        $location.search('org', "list");
-        return;
-      }
-      // don't update the data when on the operations tab
-      if ($scope.currentMode.id === 'operations') {
-        return;
-      }
-
-      var gotNodeInfo = function (nodeName, dotentity, response) {
-        if (!response.results)
-          return
-        var tableRows = [];
-        var records = response.results;
-        var aggregates = response.aggregates;
-        var attributeNames = response.attributeNames;
-        // If !attributeNmes then  there was an error getting the records for this entity
-        if (attributeNames) {
-          var nameIndex = attributeNames.indexOf("name");
-          var identityIndex = attributeNames.indexOf("identity");
-          var ent = QDRService.schema.entityTypes[entity];
-          for (var i=0; i<records.length; ++i) {
-            var record = records[i];
-            var aggregate = aggregates ? aggregates[i] : undefined;
-            var row = {};
-            var rowName;
-            if (nameIndex > -1) {
-              rowName = record[nameIndex];
-              if (!rowName && identityIndex > -1) {
-                rowName = record[nameIndex] = (dotentity + '/' + record[identityIndex])
-              }
-            }
-            if (!rowName) {
-              QDR.log.error("response attributeNames did not contain a name field");
-              console.dump(response.attributeNames);
-              return;
-            }
-            for (var j=0; j<attributeNames.length; ++j) {
-              var col = attributeNames[j];
-              row[col] = {value: record[j], type: undefined, graph: false, title: '', aggregate: '', aggregateTip: ''};
-              if (ent) {
-                var att = ent.attributes[col];
-                if (att) {
-                  row[col].type = att.type;
-                  row[col].graph = att.graph;
-                  row[col].title = att.description;
-
-                  if (aggregate) {
-                    if (att.graph) {
-                      row[col].aggregate = att.graph ? aggregate[j].sum : '';
-                      var tip = [];
-                      aggregate[j].detail.forEach( function (line) {
-                        tip.push(line);
-                      })
-                      row[col].aggregateTip = angular.toJson(tip);
-                    }
-                  }
-                }
-              }
-            }
-            tableRows.push(row);
-          }
-        }
-
-        tableRows.sort( function (a, b) { return a.name.value.localeCompare(b.name.value) })
-        setTimeout(selectRow, 0, {entity: dotentity, rows: tableRows, expand: expand});
-      }
-      // if this entity should show an aggregate column, send the request to get the info for this entity from all the nedes
-      if (aggregateEntities.indexOf(entity) > -1) {
-        var nodeInfo = QDRService.topology.nodeInfo();
-        QDRService.getMultipleNodeInfo(Object.keys(nodeInfo), entity, [], gotNodeInfo, $scope.selectedNodeId);
-      } else {
-        QDRService.fetchEntity($scope.selectedNodeId, entity, [], gotNodeInfo);
-      }
-    };
-
-    // tableRows are the records that were returned, this populates the left hand table on the page
-    var selectRow = function (info) {
-      updateEntityChildren(info.entity, info.rows, info.expand);
-      fixTooltips();
-    }
-
-    var titleFromAlt = function (alt) {
-      if (alt && alt.length) {
-        var data = angular.fromJson(alt);
-        var table = "<table class='tiptable'><tbody>";
-        data.forEach (function (row) {
-          table += "<tr>";
-          table += "<td>" + row.node + "</td><td align='right'>" + QDRService.pretty(row.val) + "</td>";
-          table += "</tr>"
-        })
-        table += "</tbody></table>"
-        return table;
-      }
-      return '';
-    }
-
-    var fixTooltips = function () {
-      if ($('.hastip').length == 0) {
-        setTimeout(fixTooltips, 100);
-        return;
-      }
-      $('.hastip').each( function (i, tip) {
-        var tipset = tip.getAttribute('tipset')
-        if (!tipset) {
-          $(tip).tipsy({html: true, className: 'subTip', opacity: 1, title: function () {
-            return titleFromAlt(this.getAttribute('alt'))
-          } });
-          tip.setAttribute('tipset', true)
-        } else {
-          var title = titleFromAlt(tip.getAttribute('alt'))
-          tip.setAttribute('original-title', title)
-        }
-      })
-    }
-
-    $scope.detailFields = [];
-
-    $scope.addToGraph = function(rowEntity) {
-      var chart = QDRChartService.registerChart(
-        {nodeId: $scope.selectedNodeId,
-         entity: "." + $scope.selectedEntity,
-         name:   $scope.selectedRecordName,
-         attr:    rowEntity.name,
-         forceCreate: true});
-      doDialog('tmplListChart.html', chart);
-    }
-
-    $scope.addAllToGraph = function(rowEntity) {
-      var chart = QDRChartService.registerChart({
-        nodeId:     $scope.selectedNodeId,
-        entity:     $scope.selectedEntity,
-        name:       $scope.selectedRecordName,
-        attr:       rowEntity.name,
-        type:       "rate",
-        rateWindow: updateInterval,
-        visibleDuration: 1,
-        forceCreate: true,
-        aggregate:   true});
-      doDialog('tmplListChart.html', chart);
-    }
-
-    $scope.detailCols = [];
-    var aggregateColumn = function () {
-      if ((aggregateEntities.indexOf($scope.selectedEntity) > -1 && $scope.detailCols.length != 3) ||
-        (aggregateEntities.indexOf($scope.selectedEntity) == -1 && $scope.detailCols.length != 2)) {
-        // column defs have to be reassigned and not spliced, so no push/pop
-         $scope.detailCols = [
-         {
-           field: 'attributeName',
-           displayName: 'Attribute',
-           cellTemplate: '<div title="{{row.entity.title}}" class="listAttrName">{{row.entity[col.field]}}<i ng-if="row.entity.graph" ng-click="addToGraph(row.entity)" ng-class="{\'icon-bar-chart\': row.entity.graph == true }"></i></div>'
-         },
-         {
-           field: 'attributeValue',
-           displayName: 'Value',
-           cellTemplate: '<div class="ngCellText" ng-class="{\'changed\': row.entity.changed == 1}"><span>{{row.getProperty(col.field)}}</span></div>'
-         }
-         ]
-        if (aggregateEntities.indexOf($scope.selectedEntity) > -1) {
-          $scope.detailCols.push(
-           {
-             width: '10%',
-             field: 'aggregateValue',
-             displayName: 'Aggregate',
-             cellTemplate: '<div class="hastip" alt="{{row.entity.aggregateTip}}"><span ng-class="{\'changed\': row.entity.changed == 1}">{{row.entity[col.field]}}</span><i ng-if="row.entity.graph" ng-click="addAllToGraph(row.entity)" ng-class="{\'icon-bar-chart\': row.entity.graph == true }"></i></div>',
-             cellClass: 'aggregate'
-           }
-          )
-        }
-      }
-      if ($scope.selectedRecordName === "")
-        $scope.detailCols = [];
-    }
-
-    // the table on the right of the page contains a row for each field in the selected record in the table on the left
-    $scope.details = {
-      data: 'detailFields',
-      columnDefs: "detailCols",
-      enableColumnResize: true,
-      multiSelect: false,
-      beforeSelectionChange: function() {
-          return false;
-      }
-    };
-    $scope.$on("$destroy", function( event ) {
-      //QDR.log.debug("scope destroyed for qdrList");
-      stopUpdating();
-      QDRService.delDisconnectAction( onDisconnect )
-    });
-
-    function gotMethodResponse (nodeName, entity, response, context) {
-      var statusCode = context.message.application_properties.statusCode;
-      if (statusCode < 200 || statusCode >= 300) {
-        Core.notification('error', context.message.statusDescription);
-        QDR.log.info('Error ' + context.message.statusDescription)
-      } else {
-        var note = entity + " " + $filter('Pascalcase')($scope.currentMode.op) + "d"
-        Core.notification('success', note);
-        QDR.log.info('Success ' + note)
-        $scope.selectMode($scope.modes[0]);
-        restartUpdate();
-      }
-    }
-    $scope.ok = function () {
-      var attributes = {}
-      $scope.detailFields.forEach( function (field) {
-        var value = field.rawValue;
-        if (field.input === 'input') {
-          if (field.type === 'text' || field.type === 'disabled')
-            value = field.attributeValue;
-        } else if (field.input === 'select') {
-          value = field.selected;
-        } else if (field.input === 'boolean') {
-          value = field.rawValue
-        }
-        if (value === "")
-          value = undefined;
-
-        if ((value && value != field['default']) || field.required || (field.name === 'role')) {
-          if (field.name !== 'identity')
-            attributes[field.name] = value
-        }
-      })
-      QDRService.sendMethod($scope.currentNode.id, $scope.selectedEntity, attributes, $scope.currentMode.op, undefined, gotMethodResponse)
-    }
-    $scope.remove = function () {
-      var attributes = {type: $scope.selectedEntity, name: $scope.selectedRecordName}
-      QDRService.sendMethod($scope.currentNode.id, $scope.selectedEntity, attributes, $scope.currentMode.op, undefined, gotMethodResponse)
-    }
-
-    function doDialog(tmpl, chart) {
-        var d = $dialog.dialog({
-          backdrop: true,
-          keyboard: true,
-          backdropClick: true,
-          templateUrl: QDR.templatePath + tmpl,
-          controller: "QDR.ListChartController",
-          resolve: {
-                 chart: function() {
-                   return chart
-                 },
-                 nodeName: function () {
-                    return $scope.selectedNode
-                 }
-              }
-        });
-
-        d.open().then(function(result) { console.log("d.open().then"); });
-
-    };
-
-    var setCurrentNode = function () {
-      $scope.nodes.some( function (node, i) {
-        if (node.name === $scope.selectedNode) {
-          $scope.currentNode = $scope.nodes[i]
-          return true;
-        }
-      })
-    }
-
-    var treeReady = false;
-    var serviceReady = false;
-    $scope.largeNetwork = QDRService.isLargeNetwork()
-    $scope.showExpandCollapseTree = function () {
-      //QDR.log.info("showExpandCollapseTree returning " + !QDRService.isMSIE())
-      return !QDRService.isMSIE()
-    }
-    // called after we know for sure the schema is fetched and the routers are all ready
-    QDRService.addUpdatedAction("initList", function () {
-      QDRService.stopUpdating();
-      QDRService.delUpdatedAction("initList")
-
-      $scope.nodes = QDRService.nodeList().sort(function (a, b) { return a.name.toLowerCase() > b.name.toLowerCase()});
-      // unable to get node list? Bail.
-      if ($scope.nodes.length == 0) {
-        $location.path(QDR.pluginRoot + "/connect")
-        $location.search('org', "list");
-      }
-      if (!angular.isDefined($scope.selectedNode)) {
-        //QDR.log.debug("selectedNode was " + $scope.selectedNode);
-        if ($scope.nodes.length > 0) {
-          $scope.selectedNode = $scope.nodes[0].name;
-          $scope.selectedNodeId = $scope.nodes[0].id;
-          //QDR.log.debug("forcing selectedNode to " + $scope.selectedNode);
-        }
-      }
-      setCurrentNode();
-      if ($scope.currentNode == undefined) {
-        if ($scope.nodes.length > 0) {
-          $scope.selectedNode = $scope.nodes[0].name;
-          $scope.selectedNodeId = $scope.nodes[0].id;
-          $scope.currentNode = $scope.nodes[0];
-        }
-      }
-      var sortedEntities = Object.keys(QDRService.schema.entityTypes).sort();
-      sortedEntities.forEach( function (entity) {
-        if (excludedEntities.indexOf(entity) == -1) {
-          if (!angular.isDefined($scope.selectedEntity))
-            $scope.selectedEntity = entity;
-          $scope.operations = lookupOperations()
-          var e = new Folder(entity)
-          e.typeName = "entity"
-          e.key = entity
-          e.expand = (expandedList.indexOf(entity) > -1)
-          var placeHolder = new Folder("loading...")
-          placeHolder.addClass = "loading"
-          e.children = [placeHolder]
-          entityTreeChildren.push(e)
-        }
-      })
-      serviceReady = true;
-      initTree();
-    })
-    $scope.treeReady = function () {
-      treeReady = true;
-      initTree();
-    }
-
-    var initTree = function () {
-      if (!treeReady || !serviceReady)
-        return;
-      $('#entityTree').dynatree({
-        onActivate: onTreeSelected,
-        onExpand: onTreeNodeExpanded,
-        selectMode: 1,
-        autoCollapse: $scope.largeNetwork,
-        activeVisible: !$scope.largeNetwork,
-        debugLevel: 0,
-        children: entityTreeChildren
-      })
-      restartUpdate()
-      updateExpandedEntities();
-    };
-    QDRService.ensureAllEntities({entity: ".connection"}, function () {
-      QDRService.setUpdateEntities([".connection"])
-      QDRService.startUpdating();
-    })
-
-
-  }]);
-
-    return QDR;
-
-} (QDR || {}));
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrListChart.js b/console/hawtio/src/main/webapp/plugin/js/qdrListChart.js
deleted file mode 100644
index 93391f1..0000000
--- a/console/hawtio/src/main/webapp/plugin/js/qdrListChart.js
+++ /dev/null
@@ -1,141 +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.
-*/
-/**
- * @module QDR
- */
-var QDR = (function(QDR) {
-
-  QDR.module.controller('QDR.ListChartController', function ($scope, dialog, $dialog, $location, QDRChartService, chart, nodeName) {
-    $scope.chart = chart;
-    $scope.dialogSvgChart = null;
-    var updateTimer = null;
-    $scope.svgDivId = "dialogChart";    // the div id for the svg chart
-
-    $scope.showChartsPage = function () {
-      cleanup();
-      dialog.close(true);
-      $location.path(QDR.pluginRoot + "/charts");
-    };
-
-    $scope.addHChart = function () {
-      QDRChartService.addHDash($scope.chart);
-      cleanup();
-      dialog.close(true);
-    }
-
-    $scope.addToDashboardLink = function () {
-      var href = "#/" + QDR.pluginName + "/charts";
-      var size = angular.toJson({
-                  size_x: 2,
-                  size_y: 2
-                });
-
-      var params = angular.toJson({chid: $scope.chart.id()});
-      var title = "Dispatch - " + nodeName;
-      return "/hawtio/#/dashboard/add?tab=dashboard" +
-        "&href=" + encodeURIComponent(href) +
-        "&routeParams=" + encodeURIComponent(params) +
-        "&title=" + encodeURIComponent(title) +
-        "&size=" + encodeURIComponent(size);
-    };
-
-
-    $scope.addChartsPage = function () {
-      QDRChartService.addDashboard($scope.chart);
-    };
-
-    $scope.delChartsPage = function () {
-      QDRChartService.delDashboard($scope.chart);
-    };
-
-    $scope.isOnChartsPage = function () {
-      return $scope.chart.dashboard;
-    }
-
-    var showChart = function () {
-      // the chart divs are generated by angular and aren't available immediately
-      var div = angular.element("#" + $scope.svgDivId);
-      if (!div.width()) {
-        setTimeout(showChart, 100);
-        return;
-      }
-      dialogSvgChart = new QDRChartService.AreaChart($scope.chart);
-      $scope.dialogSvgChart = dialogSvgChart;
-      updateDialogChart();
-    }
-    showChart();
-
-    var updateDialogChart = function () {
-      if ($scope.dialogSvgChart)
-        $scope.dialogSvgChart.tick($scope.svgDivId);
-      if (updateTimer)
-        clearTimeout(updateTimer)
-      updateTimer = setTimeout(updateDialogChart, 1000);
-    }
-
-    var cleanup = function () {
-      if (updateTimer) {
-        clearTimeout(updateTimer);
-        updateTimer = null;
-      }
-      if (!$scope.chart.hdash && !$scope.chart.dashboard)
-        QDRChartService.unRegisterChart($scope.chart);     // remove the chart
-
-    }
-    $scope.ok = function () {
-      cleanup();
-      dialog.close(true);
-      };
-
-    $scope.editChart = function () {
-      doDialog('tmplChartConfig.html', chart)
-    }
-
-    function doDialog(template, chart) {
-
-      $dialog.dialog({
-      backdrop: true,
-      keyboard: true,
-      backdropClick: true,
-      templateUrl: QDR.templatePath + template,
-      controller: "QDR.ChartDialogController",
-      resolve: {
-        chart: function() {
-          return chart;
-        },
-        updateTick: function () {
-          return function () {};
-        },
-        dashboard: function () {
-          return $scope;
-        },
-        adding: function () {
-          return true
-        }
-      }
-      }).open().then(function(result) {
-        $scope.ok()
-      });
-    };
-
-  });
-
-  return QDR;
-
-} (QDR || {}));
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrOverview.js b/console/hawtio/src/main/webapp/plugin/js/qdrOverview.js
deleted file mode 100644
index 4c0fbcf..0000000
--- a/console/hawtio/src/main/webapp/plugin/js/qdrOverview.js
+++ /dev/null
@@ -1,1686 +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.
-*/
-/**
- * @module QDR
- */
-/**
- * @module QDR
- */
-var QDR = (function (QDR) {
-
-  /**
-   * @method OverviewController
-   * @param $scope
-   * @param QDRService
-   * @param QDRChartServer
-   * dialogServer
-   * $location
-   *
-   * Controller that handles the QDR overview page
-   */
-  QDR.module.controller("QDR.OverviewController", ['$scope', 'QDRService', '$location', '$timeout', '$dialog', function($scope, QDRService, $location, $timeout, $dialog) {
-
-    var COLUMNSTATEKEY = 'QDRColumnKey.';
-    var OVERVIEWEXPANDEDKEY = "QDROverviewExpanded"
-    var OVERVIEWACTIVATEDKEY = "QDROverviewActivated"
-    var FILTERKEY = "QDROverviewFilters"
-    var OVERVIEWMODEIDS = "QDROverviewModeIds"
-    var treeRoot;   // the dynatree root node. initialized once log data is received
-
-    // we want attributes to be listed first, so add it at index 0
-    $scope.subLevelTabs = [{
-        content: '<i class="icon-list"></i> Attributes',
-        title: "View the attribute values on your selection",
-        isValid: function (workspace) { return true; },
-        href: function () { return "#/" + QDR.pluginName + "/attributes"; },
-        index: 0
-    },
-    {
-        content: '<i class="icon-leaf"></i> Operations',
-        title: "Execute operations on your selection",
-        isValid: function (workspace) { return true; },
-        href: function () { return "#/" + QDR.pluginName + "/operations"; },
-        index: 1
-    }]
-    $scope.activeTab = $scope.subLevelTabs[0];
-    $scope.setActive = function (nav) {
-      $scope.activeTab = nav;
-    }
-    $scope.isValid = function (nav) {
-      return nav.isValid()
-    }
-    $scope.isActive = function (nav) {
-      return nav == $scope.activeTab;
-    }
-    $scope.filteredLinkFields = []
-    $scope.Link = null;
-    var refreshInterval = 5000
-    $scope.modes = [
-      {title: 'Overview', name: 'Overview', right: false}
-    ];
-
-    $scope.tmplOverviewTree = QDR.templatePath + 'tmplOverviewTree.html';
-    $scope.templates = [
-      { name: 'Routers', url: 'routers.html'},
-      { name: 'Router', url: 'router.html'},
-      { name: 'Addresses', url: 'addresses.html'},
-      { name: 'Address', url: 'address.html'},
-      { name: 'Links', url: 'links.html'},
-      { name: 'Link', url: 'link.html'},
-      { name: 'Connections', url: 'connections.html'},
-      { name: 'Connection', url: 'connection.html'},
-      { name: 'Logs', url: 'logs.html'},
-      { name: 'Log', url: 'logModule.html'}
-    ];
-    var topLevelChildren = [];
-
-    $scope.allRouterSelected = function (row ) {
-      console.log("row selected" + row)
-    }
-    function afterSelectionChange(rowItem, checkAll) {
-      var nodeId = rowItem.entity.nodeId;
-      $("#overtree").dynatree("getTree").activateKey(nodeId);
-    }
-
-    $scope.routerPagingOptions = {
-      pageSizes: [50, 100, 500],
-      pageSize: 50,
-      currentPage: 1
-    };
-    var getPagedData = function (pageSize, page) {
-      $scope.totalRouters = $scope.allRouterFields.length
-      $scope.allRouters.showFooter = $scope.totalRouters > 50
-      $scope.pagedRouterFields = $scope.allRouterFields.slice((page - 1) * pageSize, page * pageSize);
-    }
-    $scope.$watch('pagingOptions', function (newVal, oldVal) {
-      if (newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) {
-        getPagedData($scope.routerPagingOptions.pageSize, $scope.routerPagingOptions.currentPage);
-      }
-    }, true);
-
-    $scope.totalRouters = 0;
-    $scope.allRouterFields = [];
-    $scope.pagedRouterFields = [];
-    $scope.allRouterSelections = [];
-    $scope.allRouters = {
-      saveKey: 'allRouters',
-      data: 'pagedRouterFields',
-      columnDefs: [
-        {
-          field: 'id',
-          saveKey: 'allRouters',
-          displayName: 'Router'
-        },
-        {
-          field: 'area',
-          displayName: 'Area'
-        },
-        {
-          field: 'mode',
-          displayName: 'Mode'
-        },
-        {
-          field: 'connections',
-          displayName: 'External connections'
-        },
-        {
-          field: 'addrCount',
-          displayName: 'Address count'
-        },
-        {
-          field: 'linkCount',
-          displayName: 'Link count'
-        }
-      ],
-      enableColumnResize: true,
-      enablePaging: true,
-      showFooter: $scope.totalRouters > 50,
-      totalServerItems: 'totalRouters',
-      pagingOptions: $scope.routerPagingOptions,
-      multiSelect: false,
-      selectedItems: $scope.allRouterSelections,
-      plugins: [new ngGridFlexibleHeightPlugin()],
-      afterSelectionChange: function(data) {
-        if (data.selected) {
-          var selItem = $scope.allRouterSelections[0]
-          var nodeId = selItem.nodeId
-          // activate Routers->nodeId in the tree
-          $("#overtree").dynatree("getTree").activateKey(nodeId);
-        }
-      }
-    };
-
-    // get info for all routers
-    var allRouterInfo = function () {
-      var nodes = {}
-      // gets called each node/entity response
-      var gotNode = function (nodeName, entity, response) {
-        if (!nodes[nodeName])
-          nodes[angular.copy(nodeName)] = {}
-        nodes[nodeName][entity] = angular.copy(response);
-      }
-      // send the requests for all connection and router info for all routers
-      QDRService.fetchAllEntities([{entity: ".connection", attrs: ["role"]}], function () {
-        QDRService.fetchAllEntities([{entity: ".router"}], function () {
-          // we have all the data now in the nodes object
-          var allRouterFields = []
-          for (var node in nodes) {
-            var connections = 0
-            for (var i=0; i<nodes[node][".connection"].results.length; ++i) {
-              // we only requested "role" so it will be at [0]
-              if (nodes[node][".connection"].results[i][0] === 'inter-router')
-                ++connections
-            }
-            var routerRow = {connections: connections, nodeId: node, id: QDRService.nameFromId(node)}
-            nodes[node][".router"].attributeNames.forEach( function (routerAttr, i) {
-              if (routerAttr !== "routerId" && routerAttr !== "id")
-                routerRow[routerAttr] = nodes[node][".router"].results[0][i]
-            })
-            allRouterFields.push(routerRow)
-          }
-          $timeout(function () {
-            $scope.allRouterFields = allRouterFields
-            getPagedData($scope.routerPagingOptions.pageSize, $scope.routerPagingOptions.currentPage);
-            updateRouterTree(nodeIds)
-            scheduleNextUpdate()
-            //if ($scope.router)
-            //  routerInfo($scope.router)
-          })
-        }, gotNode)
-      }, gotNode)
-      loadColState($scope.allRouters)
-    }
-
-    $scope.router = null;
-    // get info for a single router
-    var routerInfo = function (node) {
-      $scope.router = node
-
-      var routerFields = [];
-      $scope.allRouterFields.some( function (field) {
-        if (field.id === node.data.title) {
-          Object.keys(field).forEach ( function (key) {
-            if (key !== '$$hashKey') {
-              var attr = (key === 'connections') ? 'External connections' : key
-              routerFields.push({attribute: attr, value: field[key]})
-            }
-          })
-          return true
-        }
-      })
-      $timeout(function () {$scope.routerFields = routerFields})
-      scheduleNextUpdate()
-      loadColState($scope.routerGrid);
-    }
-
-    $scope.addressPagingOptions = {
-      pageSizes: [50, 100, 500],
-      pageSize: 50,
-      currentPage: 1
-    };
-    var getAddressPagedData = function (pageSize, page) {
-      $scope.totalAddresses = $scope.addressesData.length
-      $scope.addressesGrid.showFooter = $scope.totalAddresses > 50
-      $scope.pagedAddressesData = $scope.addressesData.slice((page - 1) * pageSize, page * pageSize);
-    }
-    $scope.$watch('addressPagingOptions', function (newVal, oldVal) {
-      if (newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) {
-        getAddressPagedData($scope.addressPagingOptions.pageSize, $scope.addressPagingOptions.currentPage);
-      }
-    }, true);
-
-    $scope.totalAddresses = 0;
-    $scope.pagedAddressesData = []
-    $scope.addressesData = []
-    $scope.selectedAddresses = []
-    $scope.addressesGrid = {
-      saveKey: 'addressesGrid',
-      data: 'pagedAddressesData',
-      columnDefs: [
-        {
-          field: 'address',
-          saveKey: 'addressesGrid',
-          displayName: 'address'
-        },
-        {
-          field: 'class',
-          displayName: 'class'
-        },
-        {
-          field: 'phase',
-          displayName: 'phase',
-          cellClass: 'grid-align-value'
-        },
-        {
-          field: 'inproc',
-          displayName: 'in-proc'
-        },
-        {
-          field: 'local',
-          displayName: 'local',
-          cellClass: 'grid-align-value'
-        },
-        {
-          field: 'remote',
-          displayName: 'remote',
-          cellClass: 'grid-align-value'
-        },
-        {
-          field: 'in',
-          displayName: 'in',
-          cellClass: 'grid-align-value'
-        },
-        {
-          field: 'out',
-          displayName: 'out',
-          cellClass: 'grid-align-value'
-        }
-      ],
-      enablePaging: true,
-      showFooter: $scope.totalAddresses > 50,
-      totalServerItems: 'totalAddresses',
-      pagingOptions: $scope.addressPagingOptions,
-      enableColumnResize: true,
-      multiSelect: false,
-      selectedItems: $scope.selectedAddresses,
-      plugins: [new ngGridFlexibleHeightPlugin()],
-      afterSelectionChange: function(data) {
-        if (data.selected) {
-          var selItem = data.entity;
-          var nodeId = selItem.uid
-          $("#overtree").dynatree("getTree").activateKey(nodeId);
-        }
-      }
-    };
-
-    // get info for all addresses
-    var allAddressInfo = function () {
-      var nodes = {}
-      // gets called each node/entity response
-      var gotNode = function (nodeName, entity, response) {
-        if (!nodes[nodeName])
-          nodes[nodeName] = {}
-        nodes[nodeName][entity] = angular.copy(response);
-      }
-      var addr_class = function (addr) {
-        if (!addr) return "-"
-            if (addr[0] == 'M')  return "mobile"
-            if (addr[0] == 'R')  return "router"
-            if (addr[0] == 'A')  return "area"
-            if (addr[0] == 'L')  return "local"
-            if (addr[0] == 'C')  return "link-incoming"
-            if (addr[0] == 'E')  return "link-incoming"
-            if (addr[0] == 'D')  return "link-outgoing"
-            if (addr[0] == 'F')  return "link-outgoing"
-            if (addr[0] == 'T')  return "topo"
-            return "unknown: " + addr[0]
-      }
-      var addr_phase = function (addr) {
-        if (!addr)
-          return "-"
-        if (addr[0] == 'M')
-          return addr[1]
-        return ''
-      }
-      var prettyVal = function (val) {
-        return QDRService.pretty(val || "-")
-      }
-      var addressFields = []
-      var addressObjs = {}
-      // send the requests for all connection and router info for all routers
-      QDRService.fetchAllEntities({entity: ".router.address"}, function () {
-        for (var node in nodes) {
-          var response = nodes[node][".router.address"]
-          response.results.forEach( function (result) {
-            var address = QDRService.flatten(response.attributeNames, result)
-
-            var addNull = function (oldVal, newVal) {
-              if (oldVal != null && newVal != null)
-                return oldVal + newVal
-              if (oldVal != null)
-                return oldVal
-              return newVal
-            }
-
-            var uid = address.identity
-            var identity = QDRService.identity_clean(uid)
-
-            if (!addressObjs[QDRService.addr_text(identity)+QDRService.addr_class(identity)])
-              addressObjs[QDRService.addr_text(identity)+QDRService.addr_class(identity)] = {
-                address: QDRService.addr_text(identity),
-                'class': QDRService.addr_class(identity),
-                phase:   addr_phase(identity),
-                inproc:  address.inProcess,
-                local:   address.subscriberCount,
-                remote:  address.remoteCount,
-                'in':    address.deliveriesIngress,
-                out:     address.deliveriesEgress,
-                thru:    address.deliveriesTransit,
-                toproc:  address.deliveriesToContainer,
-                fromproc:address.deliveriesFromContainer,
-                uid:     uid
-              }
-            else {
-              var sumObj = addressObjs[QDRService.addr_text(identity)+QDRService.addr_class(identity)]
-              sumObj.inproc = addNull(sumObj.inproc, address.inproc)
-              sumObj.local = addNull(sumObj.local, address.local)
-              sumObj.remote = addNull(sumObj.remote, address.remote)
-              sumObj['in'] = addNull(sumObj['in'], address['in'])
-              sumObj.out = addNull(sumObj.out, address.out)
-              sumObj.thru = addNull(sumObj.thru, address.thru)
-              sumObj.toproc = addNull(sumObj.toproc, address.toproc)
-              sumObj.fromproc = addNull(sumObj.fromproc, address.fromproc)
-            }
-          })
-        }
-        for (var obj in addressObjs) {
-          addressObjs[obj].inproc = prettyVal(addressObjs[obj].inproc)
-          addressObjs[obj].local = prettyVal(addressObjs[obj].local)
-          addressObjs[obj].remote = prettyVal(addressObjs[obj].remote)
-          addressObjs[obj]['in'] = prettyVal(addressObjs[obj]['in'])
-          addressObjs[obj].out = prettyVal(addressObjs[obj].out)
-          addressObjs[obj].thru = prettyVal(addressObjs[obj].thru)
-          addressObjs[obj].toproc = prettyVal(addressObjs[obj].toproc)
-          addressObjs[obj].fromproc = prettyVal(addressObjs[obj].fromproc)
-          addressFields.push(addressObjs[obj])
-        }
-        if (addressFields.length === 0)
-          return;
-        // update the grid's data
-        addressFields.sort ( function (a,b) {
-          return a.address + a['class'] < b.address + b['class'] ? -1 : a.address + a['class'] > b.address + b['class'] ? 1 : 0}
-        )
-        // callapse all records with same addres+class
-        for (var i=1; i<addressFields.length; ++i) {
-
-        }
-        addressFields[0].title = addressFields[0].address
-        for (var i=1; i<addressFields.length; ++i) {
-          // if this address is the same as the previous address, add a class to the display titles
-          if (addressFields[i].address === addressFields[i-1].address) {
-            addressFields[i-1].title = addressFields[i-1].address + " (" + addressFields[i-1]['class'] + ")"
-            addressFields[i].title = addressFields[i].address + " (" + addressFields[i]['class'] + ")"
-          } else
-            addressFields[i].title = addressFields[i].address
-        }
-        $timeout(function () {
-          $scope.addressesData = addressFields
-          getAddressPagedData($scope.addressPagingOptions.pageSize, $scope.addressPagingOptions.currentPage);
-          // repopulate the tree's child nodes
-          updateAddressTree(addressFields)
-          scheduleNextUpdate()
-        })
-      }, gotNode)
-      loadColState($scope.addressesGrid);
-    }
-
-    var updateLinkGrid = function ( linkFields ) {
-      // apply the filter
-      var filteredLinks = linkFields.filter( function (link) {
-        var include = true;
-        if ($scope.filter.endpointsOnly === "true") {
-          if (link.linkType !== 'endpoint')
-            include = false;
-        }
-        if ($scope.filter.hideConsoles) {
-          if (QDRService.isConsoleLink(link))
-            include = false;
-        }
-        return include;
-      })
-      QDR.log.debug("setting linkFields in updateLinkGrid filteredLinks.length=" + filteredLinks.length)
-      $scope.filteredLinkFields = filteredLinks;
-      getLinkPagedData($scope.linkPagingOptions.pageSize, $scope.linkPagingOptions.currentPage);
-      // if we have a selected link
-      if ($scope.Link) {
-        // find the selected link in the array of all links
-        var links = $scope.filteredLinkFields.filter(function (link) {
-          return link.name === $scope.Link.data.fields.name;
-        })
-        if (links.length > 0) {
-          // linkInfo() is the function that is called by dynatree when a link is selected
-          // It is passed a dynatree node. We need to simulate that node type to update the link grid
-          $scope.Link.data.info({data: {title: links[0].title, fields: links[0]}})
-          //linkInfo({data: {title: links[0].title, fields: links[0]}})
-        }
-      }
-    }
-
-    // get info for a all links
-    $scope.linkPagingOptions = {
-      pageSizes: [50, 100, 500],
-      pageSize: 50,
-      currentPage: 1
-    };
-    var getLinkPagedData = function (pageSize, page) {
-      $scope.totalLinks = $scope.filteredLinkFields.length
-      $scope.linksGrid.showFooter = $scope.totalLinks > 50
-      $scope.pagedLinkData = $scope.filteredLinkFields.slice((page - 1) * pageSize, page * pageSize);
-    }
-    $scope.$watch('linkPagingOptions', function (newVal, oldVal) {
-      if (newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) {
-        getLinkPagedData($scope.linkPagingOptions.pageSize, $scope.linkPagingOptions.currentPage);
-      }
-    }, true);
-
-    $scope.totalLinks = 0;
-    $scope.pagedLinkData = []
-    $scope.selectedLinks = []
-    $scope.linksGrid = {
-      saveKey: 'linksGrid',
-      data: 'pagedLinkData',
-      columnDefs: [
-        {
-          field: 'link',
-          displayName: 'Link',
-          groupable:  false,
-          saveKey: 'linksGrid',
-          width: '11%'
-        },
-        {
-          field: 'linkType',
-          displayName: 'Link type',
-          groupable:  false,
-          width: '9%'
-        },
-        {
-          field: 'linkDir',
-          displayName: 'Link dir',
-          groupable:  false,
-          width: '8%'
-        },
-        {
-          field: 'adminStatus',
-          displayName: 'Admin status',
-          groupable:  false,
-          width: '9%'
-        },
-        {
-          field: 'operStatus',
-          displayName: 'Oper status',
-          groupable:  false,
-          width: '9%'
-        },
-        {
-          field: 'deliveryCount',
-          displayName: 'Delivery Count',
-          groupable:  false,
-          cellClass: 'grid-align-value',
-          width: '11%'
-        },
-        {
-          field: 'rate',
-          displayName: 'Rate',
-          groupable:  false,
-          cellClass: 'grid-align-value',
-          width: '8%'
-        },
-        {
-          field: 'uncounts',
-          displayName: 'Outstanding',
-          groupable:  false,
-          cellClass: 'grid-align-value',
-          width: '9%'
-        },
-        {
-          field: 'owningAddr',
-          displayName: 'Address',
-          groupable:  false,
-          width: '15%'
-        }/*,
-        {
-          displayName: 'Quiesce',
-                    cellClass: 'gridCellButton',
-                    cellTemplate: '<button title="{{quiesceLinkText(row)}} this link" type="button" ng-class="quiesceLinkClass(row)" class="btn" ng-click="quiesceLink(row, $event)" ng-disabled="quiesceLinkDisabled(row)">{{quiesceLinkText(row)}}</button>',
-          width: '10%'
-                }*/
-            ],
-      enablePaging: true,
-      showFooter: $scope.totalLinks > 50,
-      totalServerItems: 'totalLinks',
-      pagingOptions: $scope.linkPagingOptions,
-      enableColumnResize: true,
-      enableColumnReordering: true,
-      showColumnMenu: true,
-      rowTemplate: 'linkRowTemplate.html',
-      // aggregateTemplate: "linkAggTemplate.html",
-      multiSelect: false,
-      selectedItems: $scope.selectedLinks,
-      plugins: [new ngGridFlexibleHeightPlugin()],
-      afterSelectionChange: function(data) {
-        if (data.selected) {
-          var selItem = data.entity;
-          var nodeId = selItem.uid
-          $("#overtree").dynatree("getTree").activateKey(nodeId);
-        }
-            }
-    };
-
-
-    $scope.$on('ngGridEventColumns', function (e, columns) {
-      var saveInfo = columns.map( function (col) {
-        return [col.width, col.visible]
-      })
-      var saveKey = columns[0].colDef.saveKey
-      if (saveKey)
-                localStorage.setItem(COLUMNSTATEKEY+saveKey, JSON.stringify(saveInfo));
-        })
-
-    var loadColState = function (grid) {
-      if (!grid)
-        return;
-      var columns = localStorage.getItem(COLUMNSTATEKEY+grid.saveKey);
-      if (columns) {
-        var cols = JSON.parse(columns);
-        cols.forEach( function (col, index) {
-        if (grid.columnDefs[index]) {
-          grid.columnDefs[index].width = col[0];
-          grid.columnDefs[index].visible = col[1]
-        }
-        })
-      }
-    }
-    var allLinkInfo = function () {
-      var gridCallback = function (linkFields) {
-        QDRService.ensureAllEntities({entity: ".connection", force: true}, function () {
-          // only update the grid with these fields if the List tree node is selected
-          // this is becuase we are using the link grid in other places and we don't want to overwrite it
-          if ($scope.template.name === "Links")
-            updateLinkGrid(linkFields)
-          updateLinkTree(linkFields)
-        })
-      }
-      getAllLinkFields([gridCallback, scheduleNextUpdate])
-      loadColState($scope.linksGrid);
-    }
-
-    var getAllLinkFields = function (completionCallbacks, selectionCallback) {
-      if (!$scope.filteredLinkFields) {
-        QDR.log.info("$scope.filteredLinkFields was not defined")
-        return;
-      }
-      var nodeIds = QDRService.nodeIdList()
-      var linkFields = []
-      var now = Date.now()
-      var rate = function (linkName, response, result) {
-        if (!$scope.filteredLinkFields)
-          return 0;
-        var oldname = $scope.filteredLinkFields.filter(function (link) {
-          return link.link === linkName
-        })
-        if (oldname.length === 1) {
-          var elapsed = (now - oldname[0].timestamp) / 1000;
-          if (elapsed < 0)
-            return 0
-          var delivered = QDRService.valFor(response.attributeNames, result, "deliveryCount") - oldname[0].rawDeliveryCount
-          //QDR.log.debug("elapsed " + elapsed + " delivered " + delivered)
-          return elapsed > 0 ? parseFloat(Math.round((delivered/elapsed) * 100) / 100).toFixed(2) : 0;
-        } else {
-          //QDR.log.debug("unable to find old linkName")
-          return 0
-        }
-      }
-      var expected = nodeIds.length;
-      var received = 0;
-      var gotLinkInfo = function (nodeName, entity, response) {
-        response.results.forEach( function (result) {
-          var nameIndex = response.attributeNames.indexOf('name')
-          var prettyVal = function (field) {
-            var fieldIndex = response.attributeNames.indexOf(field)
-            if (fieldIndex < 0) {
-              return "-"
-            }
-            var val = result[fieldIndex]
-            return QDRService.pretty(val)
-          }
-          var uncounts = function () {
-            var und = QDRService.valFor(response.attributeNames, result, "undeliveredCount")
-            var uns = QDRService.valFor(response.attributeNames, result, "unsettledCount")
-            return QDRService.pretty(und + uns)
-          }
-          var linkName = function () {
-            var namestr = QDRService.nameFromId(nodeName)
-            return namestr + ':' + QDRService.valFor(response.attributeNames, result, "identity")
-          }
-          var fixAddress = function () {
-            var addresses = []
-            var owningAddr = QDRService.valFor(response.attributeNames, result, "owningAddr") || ""
-            var rawAddress = owningAddr
-            /*
-                 - "L*"  =>  "* (local)"
-                 - "M0*" =>  "* (direct)"
-                 - "M1*" =>  "* (dequeue)"
-                 - "MX*" =>  "* (phase X)"
-            */
-            var address = undefined;
-            var starts = {'L': '(local)', 'M0': '(direct)', 'M1': '(dequeue)'}
-            for (var start in starts) {
-              if (owningAddr.startsWith(start)) {
-                var ends = owningAddr.substr(start.length)
-                address = ends + " " + starts[start]
-                rawAddress = ends
-                break;
-              }
-            }
-            if (!address) {
-              // check for MX*
-              if (owningAddr.length > 3) {
-                if (owningAddr[0] === 'M') {
-                  var phase = parseInt(owningAddress.substr(1))
-                  if (phase && !isNaN(phase)) {
-                    var phaseStr = phase + "";
-                    var star = owningAddress.substr(2 + phaseStr.length)
-                    address = star + " " + "(phase " + phaseStr + ")"
-                  }
-                }
-              }
-            }
-            addresses[0] = address || owningAddr
-            addresses[1] = rawAddress
-            return addresses
-          }
-          if (!selectionCallback || selectionCallback(response, result)) {
-            var adminStatus = QDRService.valFor(response.attributeNames, result, "adminStatus")
-            var operStatus = QDRService.valFor(response.attributeNames, result, "operStatus")
-            var linkName = linkName()
-            var linkType = QDRService.valFor(response.attributeNames, result, "linkType")
-            var addresses = fixAddress();
-            var link = QDRService.flatten(response.attributeNames, result)
-            linkFields.push({
-              link:       linkName,
-              title:      linkName,
-              uncounts:   uncounts(),
-              operStatus: operStatus,
-              adminStatus:adminStatus,
-              owningAddr: addresses[0],
-
-              acceptedCount: prettyVal("acceptedCount"),
-              modifiedCount: prettyVal("modifiedCount"),
-              presettledCount: prettyVal("presettledCount"),
-              rejectedCount: prettyVal("rejectedCount"),
-              releasedCount: prettyVal("releasedCount"),
-              deliveryCount:prettyVal("deliveryCount") + " ",
-
-              rate: QDRService.pretty(rate(linkName, response, result)),
-              capacity: link.capacity,
-              undeliveredCount: link.undeliveredCount,
-              unsettledCount: link.unsettledCount,
-
-              rawAddress: addresses[1],
-              rawDeliveryCount: link.deliveryCount,
-              name: link.name,
-              linkName: link.linkName,
-              connectionId: link.connectionId,
-              linkDir: link.linkDir,
-              linkType: linkType,
-              peer: link.peer,
-              type: link.type,
-
-              uid:     linkName,
-              timestamp: now,
-              nodeId: nodeName,
-              identity: link.identity,
-            })
-          }
-        })
-        if (expected === ++received) {
-          linkFields.sort ( function (a,b) { return a.link < b.link ? -1 : a.link > b.link ? 1 : 0})
-          completionCallbacks.forEach( function (cb) {
-            cb(linkFields)
-          })
-        }
-      }
-      nodeIds.forEach( function (nodeId) {
-        QDRService.fetchEntity(nodeId, "router.link", [], gotLinkInfo);
-      })
-    }
-
-    $scope.connectionPagingOptions = {
-      pageSizes: [50, 100, 500],
-      pageSize: 50,
-      currentPage: 1
-    };
-    var getConnectionPagedData = function (pageSize, page) {
-      $scope.totalConnections = $scope.allConnectionFields.length
-      $scope.allConnectionGrid.showFooter = $scope.totalConnections > 50
-      $scope.pagedConnectionsData = $scope.allConnectionFields.slice((page - 1) * pageSize, page * pageSize);
-    }
-    $scope.$watch('connectionPagingOptions', function (newVal, oldVal) {
-      if (newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) {
-        getConnectionPagedData($scope.connectionPagingOptions.pageSize, $scope.connectionPagingOptions.currentPage);
-      }
-    }, true);
-
-    $scope.totalConnections = 0;
-    $scope.pagedConnectionsData = []
-    $scope.allConnectionFields = []
-    $scope.allConnectionSelections = [];
-    $scope.allConnectionGrid = {
-      saveKey: 'allConnGrid',
-      data: 'pagedConnectionsData',
-      columnDefs: [
-      {
-        field: 'host',
-        saveKey: 'allConnGrid',
-        displayName: 'host'
-      },
-      {
-        field: 'container',
-        displayName: 'container'
-      },
-      {
-        field: 'role',
-        displayName: 'role'
-      },
-      {
-        field: 'dir',
-        displayName: 'dir'
-      },
-      {
-        field: 'security',
-        displayName: 'security'
-      },
-      {
-        field: 'authentication',
-        displayName: 'authentication'
-      },
-      ],
-      enablePaging: true,
-      showFooter: $scope.totalConnections > 50,
-      totalServerItems: 'totalConnections',
-      pagingOptions: $scope.connectionPagingOptions,
-      enableColumnResize: true,
-      multiSelect: false,
-      selectedItems: $scope.allConnectionSelections,
-      plugins: [new ngGridFlexibleHeightPlugin()],
-      afterSelectionChange: function(data) {
-        if (data.selected) {
-          var selItem = $scope.allConnectionSelections[0]
-          var nodeId = selItem.uid
-          // activate Routers->nodeId in the tree
-          $("#overtree").dynatree("getTree").activateKey(nodeId);
-        }
-      }
-    };
-    // get info for a all connections
-    var allConnectionInfo = function () {
-      getAllConnectionFields([updateConnectionGrid, updateConnectionTree, scheduleNextUpdate])
-      loadColState($scope.allConnectionGrid);
-    }
-    // called after conection data is available
-    var updateConnectionGrid = function (connectionFields) {
-      $scope.allConnectionFields = connectionFields;
-      getConnectionPagedData($scope.connectionPagingOptions.pageSize, $scope.connectionPagingOptions.currentPage);
-    }
-
-    // get the connection data for all nodes
-    // called periodically
-    // creates a connectionFields array and calls the callbacks (updateTree and updateGrid)
-    var getAllConnectionFields = function (callbacks) {
-      var nodeIds = QDRService.nodeIdList()
-      var connectionFields = [];
-      var expected = nodeIds.length;
-      var received = 0;
-      var gotConnectionInfo = function (nodeName, entity, response) {
-        response.results.forEach( function (result) {
-
-          var auth = "no_auth"
-          var sasl = QDRService.valFor(response.attributeNames, result, "sasl")
-          if (QDRService.valFor(response.attributeNames, result, "isAuthenticated")) {
-            auth = sasl
-            if (sasl === "ANONYMOUS")
-              auth = "anonymous-user"
-            else {
-              if (sasl === "GSSAPI")
-                sasl = "Kerberos"
-              if (sasl === "EXTERNAL")
-                sasl = "x.509"
-              auth = QDRService.valFor(response.attributeNames, result, "user") + "(" +
-                  QDRService.valFor(response.attributeNames, result, "sslCipher") + ")"
-              }
-          }
-
-          var sec = "no-security"
-          if (QDRService.valFor(response.attributeNames, result, "isEncrypted")) {
-            if (sasl === "GSSAPI")
-              sec = "Kerberos"
-            else
-              sec = QDRService.valFor(response.attributeNames, result, "sslProto") + "(" +
-                  QDRService.valFor(response.attributeNames, result, "sslCipher") + ")"
-          }
-
-          var host = QDRService.valFor(response.attributeNames, result, "host")
-          var connField = {
-            host: host,
-            security: sec,
-            authentication: auth,
-            routerId: nodeName,
-            uid: host + QDRService.valFor(response.attributeNames, result, "identity")
-          }
-          response.attributeNames.forEach( function (attribute, i) {
-            connField[attribute] = result[i]
-          })
-          connectionFields.push(connField)
-        })
-        if (expected === ++received) {
-          connectionFields.sort ( function (a,b) { return a.host < b.host ? -1 : a.host > b.host ? 1 : 0})
-          $timeout( function () {
-            callbacks.forEach( function (cb) {
-              cb(connectionFields)
-            })
-          })
-        }
-      }
-      nodeIds.forEach( function (nodeId) {
-        QDRService.fetchEntity(nodeId, ".connection", [], gotConnectionInfo)
-      })
-    }
-
-    var SingleEntityGrid = function (name) {
-      this.saveKey = name
-      this.data = name
-      this.columnDefs = [
-        {
-          field: 'attribute',
-          displayName: 'Attribute',
-          saveKey: this.saveKey,
-          width: '40%'
-        },
-        {
-          field: 'value',
-          displayName: 'Value',
-          width: '40%'
-        }
-        ]
-      this.enableColumnResize = true
-      this.multiSelect = false
-    }
-    $scope.addressFields = []
-    $scope.addressGrid = new SingleEntityGrid('addressFields')
-    $scope.connectionFields = []
-    $scope.connectionGrid = new SingleEntityGrid('connectionFields')
-    $scope.routerFields = []
-    $scope.routerGrid = new SingleEntityGrid('routerFields')
-    $scope.linkFields = []
-    $scope.linkGrid = new SingleEntityGrid('linkFields')
-
-    var SingleEntityInfo = function (entityName) {
-      return function (entity) {
-        if (!entity)
-          return
-        $scope[entityName] = entity
-        var currentEntity = getCurrentLinksEntity()
-        if (currentEntity === entityName && entityModes[currentEntity] && entityModes[currentEntity].currentModeId === 'links') {
-          updateModeLinks()
-          scheduleNextUpdate()
-          return
-        }
-        var filteredFields = []
-        var fields = Object.keys(entity.data.fields)
-        fields.forEach( function (field) {
-          if (field != "title" && field != "uid")
-            filteredFields.push({attribute: field, value: entity.data.fields[field]})
-        })
-        $scope[entityName.toLowerCase()+'Fields'] = filteredFields
-        scheduleNextUpdate()
-        loadColState($scope[entityName.toLowerCase()+'Grid']);
-        //$timeout(() => $scope[entityName.toLowerCase()+'Fields'] = filteredFields)
-      }
-    }
-
-    // get info for a single connection
-    $scope.gridModes = [{
-        content: '<a><i class="icon-list"></i> Attributes</a>',
-        id: 'attributes',
-        title: "View attributes"
-      },
-      {
-        content: '<a><i class="icon-link"></i> Links</a>',
-        id: 'links',
-        title: "Show links"
-      }
-    ];
-    var saveModeIds = function () {
-      var modeIds = {Address: entityModes.Address.currentModeId, Connection: entityModes.Connection.currentModeId}
-      localStorage[OVERVIEWMODEIDS] = JSON.stringify(modeIds)
-    }
-    var loadModeIds = function () {
-      return angular.fromJson(localStorage[OVERVIEWMODEIDS]) ||
-        {Address: 'attributes', Connection: 'attributes'}
-    }
-    var savedModeIds = loadModeIds()
-      var entityModes = {
-          Address: {
-              currentModeId: savedModeIds.Address,
-              filter: function (response, result) {
-          var owningAddr = QDRService.valFor(response.attributeNames, result, "owningAddr")
-          var id = $scope.Address.data.fields.uid
-          return (owningAddr === $scope.Address.data.fields.uid)
-              }
-          },
-          Connection: {
-              currentModeId: savedModeIds.Connection,
-              filter: function (response, result) {
-          var connectionId = QDRService.valFor(response.attributeNames, result, "connectionId")
-          return (connectionId === $scope.Connection.data.fields.identity)
-              }
-          }
-      }
-    $scope.selectMode = function (mode, entity) {
-      if (!mode || !entity)
-        return;
-      entityModes[entity].currentModeId = mode.id;
-      saveModeIds();
-      if (mode.id === 'links') {
-QDR.log.debug("setting linkFields to [] in selectMode")
-        $scope.filteredLinkFields = [];
-        getLinkPagedData($scope.linkPagingOptions.pageSize, $scope.linkPagingOptions.currentPage);
-        updateModeLinks();
-      }
-    }
-    $scope.isModeSelected = function (mode, entity) {
-      return mode.id === entityModes[entity].currentModeId
-    }
-    $scope.isModeVisible = function (entity, id) {
-      return entityModes[entity].currentModeId === id
-    }
-
-    var updateEntityLinkGrid = function (linkFields) {
-      $timeout(function () {
-        QDR.log.debug("setting linkFields in updateEntityLinkGrid");
-        $scope.filteredLinkFields = linkFields
-        getLinkPagedData($scope.linkPagingOptions.pageSize, $scope.linkPagingOptions.currentPage);
-      })
-    }
-    // based on which entity is selected, get and filter the links
-    var updateModeLinks = function () {
-      var currentEntity = getCurrentLinksEntity()
-      if (!currentEntity)
-        return;
-      var selectionCallback = entityModes[currentEntity].filter;
-      getAllLinkFields([updateEntityLinkGrid], selectionCallback)
-    }
-    var getCurrentLinksEntity = function () {
-      var currentEntity;
-      var active = $("#overtree").dynatree("getActiveNode");
-      if (active) {
-        currentEntity = active.data.type;
-      }
-      return currentEntity;
-    }
-
-    $scope.quiesceLinkClass = function (row) {
-      var stateClassMap = {
-        enabled: 'btn-primary',
-        disabled: 'btn-danger'
-      }
-      return stateClassMap[row.entity.adminStatus]
-    }
-
-    $scope.quiesceLink = function (row, $event) {
-      QDRService.quiesceLink(row.entity.nodeId, row.entity.name);
-      $event.stopPropagation()
-    }
-
-    $scope.quiesceLinkDisabled = function (row) {
-      return (row.entity.operStatus !== 'up' && row.entity.operStatus !== 'down')
-    }
-    $scope.quiesceLinkText = function (row) {
-      return row.entity.adminStatus === 'disabled' ? "Revive" : "Quiesce";
-    }
-
-    $scope.showExpandCollapseTree = function () {
-      QDR.log.info("showExpandCollapseTree returning " + !QDRService.isMSIE())
-      return !QDRService.isMSIE()
-    }
-    $scope.expandAll = function () {
-      $("#overtree").dynatree("getRoot").visit(function(node){
-                node.expand(true);
-            });
-    }
-    $scope.contractAll = function () {
-      $("#overtree").dynatree("getRoot").visit(function(node){
-                node.expand(false);
-            })
-    }
-
-    var logModuleCellTemplate = '<div ng-click="logInfoFor(row, col)" class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{COL_FIELD | pretty}}</span></div>'
-    $scope.logModule = {}
-    $scope.logModuleSelected = []
-    $scope.logModuleData = []
-    $scope.logModuleGrid = {
-      data: 'logModuleData',
-      columnDefs: [
-        {
-          field: 'nodeName',
-          displayName: 'Router',
-        },
-        {
-          field: 'enable',
-          displayName: 'Enable level',
-        },
-        {
-          field: 'noticeCount',
-          displayName: 'Notice',
-          cellTemplate: logModuleCellTemplate,
-          cellClass: 'grid-align-value',
-        },
-        {
-          field: 'infoCount',
-          displayName: 'Info',
-          cellTemplate: logModuleCellTemplate,
-          cellClass: 'grid-align-value',
-        },
-        {
-          field: 'traceCount',
-          displayName: 'Trace',
-          cellTemplate: logModuleCellTemplate,
-          cellClass: 'grid-align-value',
-        },
-        {
-          field: 'debugCount',
-          displayName: 'Debug',
-          cellTemplate: logModuleCellTemplate,
-          cellClass: 'grid-align-value',
-        },
-        {
-          field: 'warningCount',
-          displayName: 'Warning',
-          cellTemplate: logModuleCellTemplate,
-          cellClass: 'grid-align-value',
-        },
-        {
-          field: 'errorCount',
-          displayName: 'Error',
-          cellTemplate: logModuleCellTemplate,
-          cellClass: 'grid-align-value',
-        },
-        {
-          field: 'criticalCount',
-          displayName: 'Critical',
-          cellTemplate: logModuleCellTemplate,
-          cellClass: 'grid-align-value',
-        },
-      ],
-      enableColumnResize: true,
-      multiSelect: false,
-      selectedItems: $scope.logModuleSelected,
-      plugins: [new ngGridFlexibleHeightPlugin()],
-      afterSelectionChange: function(data) {
-        if (data.selected) {
-            var selItem = $scope.logModuleSelected[0]
-            var nodeId = selItem.nodeId
-
-        }
-      }
-    }
-
-    $scope.logInfoFor = function (row, col) {
-      logDialog(row, col)
-    }
-
-    function logDialog(row, col) {
-        var d = $dialog.dialog({
-          backdrop: false,
-          keyboard: true,
-          backdropClick: false,
-          templateUrl: 'viewLogs.html',
-          controller: "QDR.OverviewLogsController",
-          resolve: {
-            nodeName: function () {
-              return row.entity.nodeName
-            },
-            module: function () {
-              return row.entity.name
-            },
-            level: function () {
-              return col.displayName
-            },
-            nodeId: function () {
-              return row.entity.nodeId
-            },
-          }
-        });
-        d.open().then(function(result) { console.log("d.open().then"); });
-    };
-
-    var numberTemplate = '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{COL_FIELD | pretty}}</span></div>'
-    $scope.allLogFields = []
-    $scope.allLogSelections = [];
-    $scope.allLogGrid = {
-      saveKey: 'allLogGrid',
-      data: 'allLogFields',
-      columnDefs: [
-        {
-          field: 'name',
-          saveKey: 'allLogGrid',
-          displayName: 'Module'
-        },
-/*        {
-          field: 'enable',
-          displayName: 'Enable'
-        },
-*/
-
-        {
-          field: 'noticeCount',
-          displayName: 'Notice',
-          cellTemplate: numberTemplate,
-          cellClass: 'grid-align-value',
-        },
-        {
-          field: 'infoCount',
-          displayName: 'Info',
-          cellTemplate: numberTemplate,
-          cellClass: 'grid-align-value',
-        },
-        {
-          field: 'traceCount',
-          displayName: 'Trace',
-          cellTemplate: numberTemplate,
-          cellClass: 'grid-align-value',
-        },
-        {
-          field: 'debugCount',
-          displayName: 'Debug',
-          cellTemplate: numberTemplate,
-          cellClass: 'grid-align-value',
-        },
-        {
-          field: 'warningCount',
-          displayName: 'Warning',
-          cellTemplate: numberTemplate,
-          cellClass: 'grid-align-value',
-        },
-        {
-          field: 'errorCount',
-          displayName: 'Error',
-          cellTemplate: numberTemplate,
-          cellClass: 'grid-align-value',
-        },
-        {
-          field: 'criticalCount',
-          displayName: 'Critical',
-          cellTemplate: numberTemplate,
-          cellClass: 'grid-align-value',
-        },
-      ],
-      //enableCellSelection: true,
-      enableColumnResize: true,
-      multiSelect: false,
-      selectedItems: $scope.allLogSelections,
-      plugins: [new ngGridFlexibleHeightPlugin()],
-
-      afterSelectionChange: function(data) {
-        if (data.selected) {
-            var selItem = $scope.allLogSelections[0]
-            var nodeId = selItem.name
-            // activate in the tree
-            $("#overtree").dynatree("getTree").activateKey(nodeId);
-        }
-      }
-
-    };
-
-    var allLogEntries = {}
-    var allLogInfo = function () {
-        // update the count of entries for each module
-        $scope.allLogFields = []
-        var logResults = {}
-        var logDetails = {}
-
-        var gotLogStats = function (node, entity, response) {
-          logDetails[node] = []
-          response.results.forEach( function (result) {
-            var oresult = QDRService.flatten(response.attributeNames, result)
-            // make a copy for the details grid since logResults has the same object reference
-            logDetails[node].push(angular.copy(oresult))
-            if (!(oresult.name in logResults)) {
-              logResults[oresult.name] = oresult
-            }
-            else {
-              response.attributeNames.forEach( function (attr, i) {
-                if (attr.substr(attr.length-5) === 'Count') {
-                  logResults[oresult.name][attr] += result[i]
-                }
-              })
-            }
-          })
-        }
-        var gotAllLogStats = function () {
-          var sortedModules = Object.keys(logResults)
-          sortedModules.sort(function (a,b) {return a<b?-1:a>b?1:0})
-          sortedModules.forEach( function (module) {
-            $scope.allLogFields.push(logResults[module])
-          })
-          allLogEntries = logDetails
-          updateLogTree($scope.allLogFields)
-        }
-        QDRService.fetchAllEntities({entity: 'logStats'}, gotAllLogStats, gotLogStats)
-    }
-
-    $scope.logFields = []
-    // get info for a single log
-    var logInfo = function (node) {
-
-        var gotLogInfo = function (responses) {
-          $timeout(function () {
-            $scope.logModuleData = []
-            $scope.logModule.module = node.data.key
-            for (var n in responses) {
-              var moduleIndex = responses[n]['log'].attributeNames.indexOf("module")
-              var result = responses[n]['log'].results.filter( function (r) {
-                return r[moduleIndex] === node.data.key
-              })[0]
-              var logInfo = QDRService.flatten(responses[n]['log'].attributeNames, result)
-              var entry = allLogEntries[n]
-              entry.forEach( function (module) {
-                if (module.name === node.data.key) {
-                  module.nodeName = QDRService.nameFromId(n)
-                  module.nodeId = n
-                  module.enable = logInfo.enable
-                  $scope.logModuleData.push(module)
-                }
-              })
-            }
-            $scope.logModuleData.sort ( function (a,b) { return a.nodeName < b.nodeName? -1 : a.nodeName> b.nodeName? 1 : 0})
-            scheduleNextUpdate()
-          })
-        }
-        QDRService.fetchAllEntities({entity: 'log', attrs: ['module', 'enable']}, gotLogInfo)
-    }
-
-    var getExpandedList = function () {
-      if (!treeRoot)
-        return;
-      var list = [];
-      if (treeRoot.visit) {
-        treeRoot.visit(function(node){
-          if (node.isExpanded()) {
-            list.push(node.data.parent)
-          }
-          });
-      }
-      return list;
-    }
-
-    // loads the tree node name that was last selected
-    var loadActivatedNode = function () {
-      return localStorage[OVERVIEWACTIVATEDKEY] || 'Routers'
-    }
-    // saved the tree node name that is currently selected
-    var saveActivated = function (key) {
-      localStorage[OVERVIEWACTIVATEDKEY] = key;
-      lastKey = key;
-    }
-    // loads list that was saved
-    var loadExpandedNodeList = function () {
-      try {
-        return angular.fromJson(localStorage[OVERVIEWEXPANDEDKEY]) || [];
-      } catch (e) {
-        QDR.log.debug("localStorage[OVERVIEWEXPANDEDKEY]=" + localStorage[OVERVIEWEXPANDEDKEY])
-        return ["Routers"]
-      }
-    }
-    // called when a node is expanded
-    // here we save the expanded node so it can be restored when the page reloads
-    var saveExpanded = function () {
-      var list = getExpandedList();
-      localStorage[OVERVIEWEXPANDEDKEY] = JSON.stringify(list)
-      expandedNodeList = list
-    }
-
-    var setTemplate = function (node) {
-      var type = node.data.type;
-      var template = $scope.templates.filter( function (tpl) {
-        return tpl.name == type;
-      })
-      $scope.template = template[0];
-    }
-    // activated is called each time a tree node is clicked
-    // based on which node is clicked, load the correct data grid template and start getting the data
-    var activated = function (node) {
-      QDR.log.debug("node activated: " + node.data.title)
-      saveExpanded()
-      saveActivated(node.data.key)
-
-      setTemplate(node)
-      // the nodes info function will fetch the grids data
-      if (node.data.info) {
-        $timeout(function () {
-          if (node.data.key === node.data.parent) {
-            node.data.info()
-          }
-          else {
-            node.data.info(node)
-          }
-        })
-      }
-    }
-
-    var treeNodeExpanded = function (node) {
-      saveExpanded()
-      tick()
-    }
-    $scope.template = {url: ''};
-
-    if (!QDRService.connected) {
-      QDRService.redirectWhenConnected("overview")
-      return;
-    }
-
-    // we are currently connected. setup a handler to get notified if we are ever disconnected
-    var onDisconnect = function () {
-      $timeout(function () { QDRService.redirectWhenConnected("overview") })
-    }
-    QDRService.addDisconnectAction( onDisconnect )
-
-    /* --------------------------------------------------
-     *
-     * setup the tree on the left
-     *
-     * -------------------------------------------------
-     */
-    // utility function called by each top level tree node when it needs to populate its child nodes
-    var updateLeaves = function (leaves, parentKey, parentFolder, worker) {
-      var scrollTree = $('.qdr-overview.pane.left .pane-viewport')
-      var scrollTop = scrollTree.scrollTop();
-      var tree = $("#overtree").dynatree("getTree")
-      if (!tree.getNodeByKey) {
-        return
-      }
-      var parentNode = tree.getNodeByKey(parentKey);
-      parentNode.removeChildren();
-
-      leaves.forEach( function (leaf) {
-        parentNode.addChild(worker(leaf))
-      })
-      scrollTree.scrollTop(scrollTop)
-      if (firstTime) {
-        var newActive = tree.getActiveNode();
-        if (newActive &&
-//            newActive.data.key === lastKey &&
-            newActive.data.key !== newActive.data.parent &&  // this is a leaf node
-            newActive.data.parent === parentKey) {          // the active node was just created
-          firstTime = false
-QDR.log.debug("newly created node needs to be activated")
-          activated(newActive)
-        }
-      }
-      $('.dynatree-title').each( function (idx) {
-        //QDR.log.info('found a title of ' + $(this).html())
-        var unsafe = $(this).html()
-        $(this).html(unsafe.replace(/</g, "&lt;").replace(/>/g, "&gt;"))
-      })
-   }
-
-    // get saved tree state
-    var lastKey = loadActivatedNode();
-    var expandedNodeList = loadExpandedNodeList();
-    var firstTime = true;
-
-    // create a routers tree branch
-    var routers = new Folder("Routers")
-    routers.type = "Routers"
-    routers.info = allRouterInfo
-    routers.activate = lastKey === 'Routers'
-    routers.expand = (expandedNodeList.indexOf("Routers") > -1)
-    routers.clickFolderMode = 1
-    routers.key = "Routers"
-    routers.parent = "Routers"
-    routers.addClass = "routers"
-    topLevelChildren.push(routers)
-    // called when the list of routers changes
-    var updateRouterTree = function (nodes) {
-      var worker = function (node) {
-        var name = QDRService.nameFromId(node)
-        var router = new Folder(name)
-        router.type = "Router"
-        router.info = routerInfo
-        router.nodeId = node
-        router.key = node
-        router.addClass = "router"
-        router.parent = "Routers"
-        router.activate = lastKey === node
-        return router;
-      }
-      $timeout(function () {updateLeaves(nodes, "Routers", routers, worker)})
-    }
-
-    // create an addresses tree branch
-    var addresses = new Folder("Addresses")
-    addresses.type = "Addresses"
-    addresses.info = allAddressInfo
-    addresses.activate = lastKey === 'Addresses'
-    addresses.expand = (expandedNodeList.indexOf("Addresses") > -1)
-    addresses.clickFolderMode = 1
-    addresses.key = "Addresses"
-    addresses.parent = "Addresses"
-    addresses.addClass = "addresses"
-    topLevelChildren.push(addresses)
-    var updateAddressTree = function (addressFields) {
-      var info = SingleEntityInfo('Address')
-      var worker = function (address) {
-        var a = new Folder(address.title)
-        a.info = info
-        a.key = address.uid
-        a.fields = address
-        a.type = "Address"
-        a.tooltip = address['class'] + " address"
-        if (address.address === '$management')
-          a.tooltip = "internal " + a.tooltip
-        a.addClass = a.tooltip
-        a.activate = lastKey === address.uid
-        a.parent = "Addresses"
-        return a;
-      }
-      $timeout(function () {updateLeaves(addressFields, "Addresses", addresses, worker)})
-    }
-
-    $scope.$watch("filter", function (newValue, oldValue) {
-      if (newValue !== oldValue) {
-        $timeout(allLinkInfo);
-        localStorage[FILTERKEY] = JSON.stringify($scope.filter)
-      }
-    }, true)
-
-    $scope.filterToggle = function () {
-      var filter = $('#linkFilter')
-      filter.toggle();
-    }
-
-    $scope.filter = angular.fromJson(localStorage[FILTERKEY]) || {endpointsOnly: "true", hideConsoles: true};
-    var links = new Folder("Links")
-    links.type = "Links"
-    links.info = allLinkInfo
-    links.activate = lastKey === 'Links'
-    links.expand = (expandedNodeList.indexOf("Links") > -1)
-    links.clickFolderMode = 1
-    links.key = "Links"
-    links.parent = "Links"
-    links.addClass = "links"
-    topLevelChildren.push(links)
-
-    // called both before the tree is created and whenever a background update is done
-    var updateLinkTree = function (linkFields) {
-      var info = SingleEntityInfo('Link')
-      var worker = function (link) {
-        var l = new Folder(link.title)
-        var isConsole = QDRService.isConsoleLink(link)
-        l.info = info
-        l.key = link.uid
-        l.fields = link
-        l.type = "Link"
-        l.parent = "Links"
-        l.activate = lastKey === link.uid
-        if (isConsole)
-          l.tooltip = "console link"
-        else
-          l.tooltip = link.linkType  + " link"
-        l.addClass = l.tooltip
-        return l;
-      }
-      $timeout(function () {updateLeaves(linkFields, "Links", links, worker)})
-    }
-
-    var connections = new Folder("Connections")
-    connections.type = "Connections"
-    connections.info = allConnectionInfo
-    connections.activate = lastKey === 'Connections'
-    connections.expand = (expandedNodeList.indexOf("Connections") > -1)
-    connections.clickFolderMode = 1
-    connections.key = "Connections"
-    connections.parent = "Connections"
-    connections.addClass = "connections"
-    topLevelChildren.push(connections)
-
-    updateConnectionTree = function (connectionFields) {
-      var info = SingleEntityInfo('Connection')
-      //var info = ConnectionInfo
-      var worker = function (connection) {
-        var c = new Folder(connection.host)
-        var isConsole = QDRService.isAConsole (connection.properties, connection.identity, connection.role, connection.routerId)
-        c.type = "Connection"
-        c.info = info
-        c.key = connection.uid
-        c.fields = connection
-        if (isConsole)
-          c.tooltip = "console connection"
-        else
-          c.tooltip = connection.role === "inter-router" ? "inter-router connection" : "external connection"
-        c.addClass = c.tooltip
-        c.parent = "Connections"
-        c.activate = lastKey === connection.uid
-        return c
-      }
-      $timeout(function () {updateLeaves(connectionFields, "Connections", connections, worker)})
-    }
-
-    var updateLogTree = function (logFields) {
-      var worker = function (log) {
-        var l = new Folder(log.name)
-        l.type = "Log"
-        l.info = logInfo
-        l.key = log.name
-        l.parent = "Logs"
-        l.activate = lastKey === l.key
-        l.addClass = "log"
-        return l
-      }
-      $timeout(function () {updateLeaves(logFields, "Logs", logs, worker)})
-    }
-
-    var htmlReady = false;
-    var dataReady = false;
-    $scope.largeNetwork = QDRService.isLargeNetwork()
-    var logs = new Folder("Logs")
-    logs.type = "Logs"
-    logs.info = allLogInfo
-    logs.activate = lastKey === 'Logs'
-    logs.expand = (expandedNodeList.indexOf("Logs") > -1)
-    logs.clickFolderMode = 1
-    logs.key = "Logs"
-    logs.parent = "Logs"
-    if (QDRService.versionCheck('0.8.0'))
-      topLevelChildren.push(logs)
-    var initTreeAndGrid = function () {
-      if (!htmlReady || !dataReady)
-        return;
-      var div = angular.element("#overtree");
-      if (!div.width()) {
-        setTimeout(initTreeAndGrid, 100);
-        return;
-      }
-      $('#overtree').dynatree({
-        onActivate: activated,
-        onExpand: treeNodeExpanded,
-        autoCollapse: $scope.largeNetwork,
-        activeVisible: !$scope.largeNetwork,
-        selectMode: 1,
-        debugLevel: 0,
-        children: topLevelChildren
-      })
-      treeRoot = $("#overtree").dynatree("getRoot");
-      tick()
-      loadColState($scope.allRouters);
-      loadColState($scope.routerGrid);
-      loadColState($scope.addressesGrid);
-      loadColState($scope.addressGrid);
-      loadColState($scope.linksGrid);
-      loadColState($scope.linkGrid);
-      loadColState($scope.allConnectionGrid);
-      loadColState($scope.connectionGrid);
-    }
-
-    $scope.overviewLoaded = function () {
-      htmlReady = true;
-      initTreeAndGrid();
-    }
-
-    var nodeIds = QDRService.nodeIdList()
-    //updateRouterTree(nodeIds);
-    // add placeholders for the top level tree nodes
-    var topLevelTreeNodes = [routers, addresses, links, connections, logs]
-    topLevelTreeNodes.forEach( function (parent) {
-      var placeHolder = new Folder("loading...")
-      placeHolder.addClass = "loading"
-      parent.children = [placeHolder]
-    })
-
-    var singleQ = null
-    var updateExpanded = function () {
-      if (!treeRoot)
-        return;
-      if (treeRoot.visit) {
-        treeRoot.visit(function(node){
-          if (node.isActive())
-            setTemplate(node)
-          if (node.isActive() || node.isExpanded()) {
-            if (node.data.key === node.data.parent) {
-              node.data.info()
-            }
-            else {
-              node.data.info(node)
-            }
-          }
-        })
-      }
-    }
-
-    var tickTimer;
-    var scheduleNextUpdate = function () {
-      clearTimeout(tickTimer)
-      tickTimer = setTimeout(tick, refreshInterval)
-    }
-    var tick = function () {
-      clearTimeout(tickTimer)
-      $timeout( updateExpanded )
-    }
-    dataReady = true;
-    initTreeAndGrid();
-    $scope.$on("$destroy", function( event ) {
-      clearTimeout(tickTimer)
-      QDRService.delDisconnectAction( onDisconnect )
-    });
-
-  }]);
-
-  return QDR;
-
-}(QDR || {}));
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrOverviewLogsController.js b/console/hawtio/src/main/webapp/plugin/js/qdrOverviewLogsController.js
deleted file mode 100644
index 510ae76..0000000
--- a/console/hawtio/src/main/webapp/plugin/js/qdrOverviewLogsController.js
+++ /dev/null
@@ -1,68 +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.
-*/
-/**
- * @module QDR
- */
-var QDR = (function(QDR) {
-
-  QDR.module.controller('QDR.OverviewLogsController', function ($scope, dialog, QDRService, $timeout, nodeName, nodeId, module, level) {
-
-      var gotLogInfo = function (nodeId, entity, response, context) {
-        var statusCode = context.message.application_properties.statusCode;
-        if (statusCode < 200 || statusCode >= 300) {
-          Core.notification('error', context.message.statusDescription);
-          QDR.log.info('Error ' + context.message.statusDescription)
-        } else {
-          var levelLogs = response.filter( function (result) {
-            if (result[1] == null)
-              result[1] = "error"
-            return result[1].toUpperCase() === level.toUpperCase() && result[0] === module
-          })
-          var logFields = levelLogs.map( function (result) {
-            return {
-              nodeId: QDRService.nameFromId(nodeId),
-              name: result[0],
-              type: result[1],
-              message: result[2],
-              source: result[3],
-              line: result[4],
-              time: Date(result[5]).toString()
-            }
-          })
-          $timeout(function () {
-            $scope.loading = false
-            $scope.logFields = logFields
-          })
-        }
-      }
-      QDRService.sendMethod(nodeId, undefined, {}, "GET-LOG", {module: module}, gotLogInfo)
-
-    $scope.loading = true
-    $scope.module = module
-    $scope.level = level
-    $scope.nodeName = nodeName
-    $scope.logFields = []
-    $scope.ok = function () {
-      dialog.close(true);
-    };
-
-  });
-  return QDR;
-
-} (QDR || {}));
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrSchema.js b/console/hawtio/src/main/webapp/plugin/js/qdrSchema.js
deleted file mode 100644
index 7365d5a..0000000
--- a/console/hawtio/src/main/webapp/plugin/js/qdrSchema.js
+++ /dev/null
@@ -1,81 +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.
-*/
-/**
- * @module QDR
- */
-var QDR = (function (QDR) {
-
-  QDR.module.controller("QDR.SchemaController", ['$scope', '$location', '$timeout', 'QDRService', function($scope, $location, $timeout, QDRService) {
-    if (!QDRService.connected) {
-      QDRService.redirectWhenConnected("schema")
-      return;
-    }
-    var onDisconnect = function () {
-      $timeout( function () {QDRService.redirectWhenConnected("schema")})
-    }
-    // we are currently connected. setup a handler to get notified if we are ever disconnected
-    QDRService.addDisconnectAction( onDisconnect )
-
-    var keys2kids = function (tree, obj) {
-      if (obj === Object(obj)) {
-        tree.children = []
-        var keys = Object.keys(obj).sort()
-        for (var i=0; i<keys.length; ++i) {
-          var key = keys[i];
-          var kid = {title: key}
-          if (obj[key] === Object(obj[key])) {
-              kid.isFolder = true
-              keys2kids(kid, obj[key])
-          } else {
-            kid.title += (': ' + JSON.stringify(obj[key],null,2))
-          }
-          tree.children.push(kid)
-        }
-      }
-    }
-
-    var tree = []
-    for (var key in QDRService.schema) {
-      var kid = {title: key}
-      kid.isFolder = true
-      var val = QDRService.schema[key]
-      if (val === Object(val))
-        keys2kids(kid, val)
-      else
-        kid.title += (': ' + JSON.stringify(val,null,2))
-
-      tree.push(kid);
-    }
-    $('#schema').dynatree({
-      minExpandLevel: 2,
-      classNames: {
-        expander: 'fa-angle',
-        connector: 'dynatree-no-connector'
-      },
-      children: tree
-    })
-
-      $scope.$on("$destroy", function(event) {
-        QDRService.delDisconnectAction( onDisconnect )
-      });
-
-  }]);
-
-    return QDR;
-}(QDR || {}));
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrService.js b/console/hawtio/src/main/webapp/plugin/js/qdrService.js
deleted file mode 100644
index 6b4a531..0000000
--- a/console/hawtio/src/main/webapp/plugin/js/qdrService.js
+++ /dev/null
@@ -1,1238 +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.
-*/
-/**
- * @module QDR
- */
-var QDR = (function(QDR) {
-
-  // The QDR service handles the connection to
-  // the server in the background
-  QDR.module.factory("QDRService", ['$rootScope', '$http', '$timeout', '$resource', '$location', function($rootScope, $http, $timeout, $resource, $location) {
-    var self = {
-
-      rhea: require("rhea"),
-      timeout: 10,             // seconds to wait before assuming a request has failed
-      updateInterval: 2000,   // milliseconds between background updates
-      connectActions: [],
-      disconnectActions: [],
-      updatedActions: {},
-      updating: false,        // are we updating the node list in the background
-      maxCorrelatorDepth: 10, // max number of outstanding requests to allow
-
-      /*
-       * @property message
-       * The proton message that is used to send commands
-       * and receive responses
-       */
-      sender: undefined,
-      receiver: undefined,
-      version: undefined,
-      sendable: false,
-
-      schema: undefined,
-
-      connected: false,
-      gotTopology: false,
-      errorText: undefined,
-      connectionError: undefined,
-
-      addConnectAction: function(action) {
-        if (angular.isFunction(action)) {
-          self.connectActions.push(action);
-        }
-      },
-      addDisconnectAction: function(action) {
-        if (angular.isFunction(action)) {
-          self.disconnectActions.push(action);
-        }
-      },
-      delDisconnectAction: function(action) {
-        if (angular.isFunction(action)) {
-          var index = self.disconnectActions.indexOf(action)
-          if (index >= 0)
-            self.disconnectActions.splice(index, 1)
-        }
-      },
-      addUpdatedAction: function(key, action) {
-        if (angular.isFunction(action)) {
-          self.updatedActions[key] = action;
-        }
-      },
-      delUpdatedAction: function(key) {
-        if (key in self.updatedActions)
-          delete self.updatedActions[key];
-      },
-
-      executeConnectActions: function() {
-        self.connectActions.forEach(function(action) {
-          try {
-            action.apply();
-          } catch (e) {
-            // in case the page that registered the handler has been unloaded
-            QDR.log.info(e.message)
-          }
-        });
-        self.connectActions = [];
-      },
-      executeDisconnectActions: function() {
-        self.disconnectActions.forEach(function(action) {
-          try {
-            action.apply();
-          } catch (e) {
-            // in case the page that registered the handler has been unloaded
-          }
-        });
-        self.disconnectActions = [];
-      },
-      executeUpdatedActions: function() {
-        for (action in self.updatedActions) {
-//          try {
-            self.updatedActions[action].apply();
-/*          } catch (e) {
-QDR.log.debug("caught error executing updated actions")
-console.dump(e)
-            delete self.updatedActions[action]
-          }
-          */
-        }
-      },
-      redirectWhenConnected: function(org) {
-        $location.path(QDR.pluginRoot + "/connect")
-        $location.search('org', org);
-      },
-
-      notifyTopologyDone: function() {
-        if (!self.gotTopology) {
-          QDR.log.debug("topology was just initialized");
-          //console.dump(self.topology._nodeInfo)
-          self.gotTopology = true;
-          //$rootScope.$apply();
-        } else {
-          //QDR.log.debug("topology model was just updated");
-        }
-        self.executeUpdatedActions();
-
-      },
-
-      isConnected: function() {
-        return self.connected;
-      },
-
-      versionCheck: function (minVer) {
-        var verparts = self.version.split('.')
-        var minparts = minVer.split('.')
-        try {
-          for (var i=0; i<minparts.length; ++i) {
-            if (parseInt(minVer[i] > parseInt(verparts[i])))
-              return false
-          }
-        } catch (e) {
-          QDR.log.debug("error doing version check between: " + self.version + " and " + minVer + " " + e.message)
-          return false
-        }
-        return true
-      },
-
-      correlator: {
-        _objects: {},
-        _correlationID: 0,
-
-        corr: function() {
-          var id = ++this._correlationID + "";
-          this._objects[id] = {
-            resolver: null
-          }
-          return id;
-        },
-        request: function() {
-          //QDR.log.debug("correlator:request");
-          return this;
-        },
-        then: function(id, resolver, error) {
-          //QDR.log.debug("registered then resolver for correlationID: " + id);
-          if (error) {
-            //QDR.log.debug("then received an error. deleting correlator")
-            delete this._objects[id];
-            return;
-          }
-          this._objects[id].resolver = resolver;
-        },
-        // called by receiver's on('message') handler when a response arrives
-        resolve: function(context) {
-          var correlationID = context.message.correlation_id;
-          this._objects[correlationID].resolver(context.message.body, context);
-          delete this._objects[correlationID];
-        },
-        depth: function () {
-          return Object.keys(this._objects).length
-        }
-      },
-
-      onSubscription: function() {
-        self.executeConnectActions();
-        var org = $location.search()
-        if (org)
-          org = org.org
-        if (org && org.length > 0 && org !== "connect") {
-          self.getSchema(function () {
-            self.setUpdateEntities([])
-            self.topology.get()
-            self.addUpdatedAction('onSub', function () {
-              self.delUpdatedAction('onSub')
-              $timeout( function () {
-                $location.path(QDR.pluginRoot + '/' + org)
-                $location.search('org', null)
-                $location.replace()
-              })
-            })
-          });
-        }
-      },
-
-      startUpdating: function() {
-        self.stopUpdating(true);
-        QDR.log.info("startUpdating called")
-        self.updating = true;
-        self.topology.get();
-      },
-      stopUpdating: function(silent) {
-        self.updating = false;
-        if (self.topology._getTimer) {
-          clearTimeout(self.topology._getTimer)
-          self.topology._getTimer = null;
-        }
-        if (self.topology._waitTimer) {
-          clearTimeout(self.topology._waitTimer)
-          self.topology._waitTimer = null;
-        }
-        if (self.topology._gettingTopo) {
-          if (self.topology.q)
-            self.topology.q.abort()
-        }
-        if (!silent)
-          QDR.log.info("stopUpdating called")
-      },
-
-      cleanUp: function() {},
-      error: function(line) {
-        if (line.num) {
-          QDR.log.debug("error - num: ", line.num, " message: ", line.message);
-        } else {
-          QDR.log.debug("error - message: ", line.message);
-        }
-      },
-      disconnected: function(line) {
-        QDR.log.debug("Disconnected from QDR server");
-        self.executeDisconnectActions();
-      },
-
-      nameFromId: function(id) {
-        // the router id looks like 'amqp:/topo/0/routerName/$managemrnt'
-        var parts = id.split('/')
-        // handle cases where the router name contains a /
-        parts.splice(0, 3)  // remove amqp, topo, 0
-        parts.pop()         // remove $management
-        return parts.join('/')
-      },
-
-      humanify: function(s) {
-        if (!s || s.length === 0)
-          return s;
-        var t = s.charAt(0).toUpperCase() + s.substr(1).replace(/[A-Z]/g, ' $&');
-        return t.replace(".", " ");
-      },
-      pretty: function(v) {
-        var formatComma = d3.format(",");
-        if (!isNaN(parseFloat(v)) && isFinite(v))
-          return formatComma(v);
-        return v;
-      },
-
-      nodeNameList: function() {
-        var nl = [];
-        for (var id in self.topology._nodeInfo) {
-          nl.push(self.nameFromId(id));
-        }
-        return nl.sort();
-      },
-
-      nodeIdList: function() {
-        var nl = [];
-        for (var id in self.topology._nodeInfo) {
-          nl.push(id);
-        }
-        return nl.sort();
-      },
-
-      nodeList: function() {
-        var nl = [];
-        for (var id in self.topology._nodeInfo) {
-          nl.push({
-            name: self.nameFromId(id),
-            id: id
-          });
-        }
-        return nl;
-      },
-
-      isLargeNetwork: function () {
-        return Object.keys(self.topology._nodeInfo).length >= 12
-      },
-      isMSIE: function () {
-        return (document.documentMode || /Edge/.test(navigator.userAgent))
-      },
-
-      // given an attribute name array, find the value at the same index in the values array
-      valFor: function(aAr, vAr, key) {
-        var idx = aAr.indexOf(key);
-        if ((idx > -1) && (idx < vAr.length)) {
-          return vAr[idx];
-        }
-        return null;
-      },
-
-      isArtemis: function(d) {
-        return (d.nodeType === 'route-container' || d.nodeType === 'on-demand') && (d.properties && d.properties.product === 'apache-activemq-artemis');
-      },
-
-      isQpid: function(d) {
-        return (d.nodeType === 'route-container' || d.nodeType === 'on-demand') && (d.properties && d.properties.product === 'qpid-cpp');
-      },
-
-      isAConsole: function(properties, connectionId, nodeType, key) {
-        return self.isConsole({
-          properties: properties,
-          connectionId: connectionId,
-          nodeType: nodeType,
-          key: key
-        })
-      },
-      isConsole: function(d) {
-        // use connection properties if available
-        return (d && d['properties'] && d['properties']['console_identifier'] === 'Dispatch console')
-      },
-
-      flatten: function(attributes, result) {
-        var flat = {}
-        attributes.forEach(function(attr, i) {
-          if (result && result.length > i)
-            flat[attr] = result[i]
-        })
-        return flat;
-      },
-      isConsoleLink: function(link) {
-        // find the connection for this link
-        var conns = self.topology.nodeInfo()[link.nodeId]['.connection']
-        var connIndex = conns.attributeNames.indexOf("identity")
-        var linkCons = conns.results.filter(function(conn) {
-          return conn[connIndex] === link.connectionId;
-        })
-        var conn = self.flatten(conns.attributeNames, linkCons[0]);
-
-        return self.isConsole(conn)
-      },
-
-      quiesceLink: function(nodeId, name) {
-        function gotMethodResponse(nodeName, entity, response, context) {
-          var statusCode = context.message.application_properties.statusCode;
-          if (statusCode < 200 || statusCode >= 300) {
-            Core.notification('error', context.message.statusDescription);
-            QDR.log.info('Error ' + context.message.statusDescription)
-          }
-        }
-        var attributes = {
-          adminStatus: 'disabled',
-          name: name
-        };
-        self.sendMethod(nodeId, "router.link", attributes, "UPDATE", undefined, gotMethodResponse)
-      },
-      addr_text: function(addr) {
-        if (!addr)
-          return "-"
-        if (addr[0] == 'M')
-          return addr.substring(2)
-        else
-          return addr.substring(1)
-      },
-      addr_class: function(addr) {
-        if (!addr) return "-"
-        if (addr[0] == 'M') return "mobile"
-        if (addr[0] == 'R') return "router"
-        if (addr[0] == 'A') return "area"
-        if (addr[0] == 'L') return "local"
-        if (addr[0] == 'C') return "link-incoming"
-        if (addr[0] == 'E') return "link-incoming"
-        if (addr[0] == 'D') return "link-outgoing"
-        if (addr[0] == 'F') return "link-outgoing"
-        if (addr[0] == 'T') return "topo"
-        return "unknown: " + addr[0]
-      },
-      identity_clean: function(identity) {
-        if (!identity)
-          return "-"
-        var pos = identity.indexOf('/')
-        if (pos >= 0)
-          return identity.substring(pos + 1)
-        return identity
-      },
-
-      queueDepth: function () {
-        var qdepth = self.maxCorrelatorDepth - self.correlator.depth()
-        if (qdepth <= 0)
-          qdepth = 1;
-//QDR.log.debug("queueDepth requested " + qdepth + "(" + self.correlator.depth() + ")")
-        return qdepth;
-      },
-      // check if all nodes have this entity. if not, get them
-      initEntity: function (entity, callback) {
-        var callNeeded = Object.keys(self.topology._nodeInfo).some( function (node) {
-          return !angular.isDefined(self.topology._nodeInfo[node][entity])
-        })
-        if (callNeeded) {
-          self.loadEntity(entity, callback)
-        } else
-          callback()
-      },
-
-      // get/refresh entities for all nodes
-      loadEntity: function (entities, callback) {
-        if (Object.prototype.toString.call(entities) !== '[object Array]') {
-          entities = [entities]
-        }
-        var q = QDR.queue(self.queueDepth())
-        for (node in self.topology._nodeInfo) {
-          for (var i=0; i<entities.length; ++i) {
-            var entity = entities[i]
-            q.defer(self.ensureNodeInfo, node, entity, [], q)
-          }
-        }
-        q.await(function (error) {
-          clearTimeout(self.topology._waitTimer)
-          callback();
-        })
-      },
-
-      // enusre all the topology nones have all these entities
-      ensureAllEntities: function (entityAttribs, callback, extra) {
-        self.ensureEntities(Object.keys(self.topology._nodeInfo), entityAttribs, callback, extra)
-      },
-
-      // ensure these nodes have all these entities. don't fetch unless forced to
-      ensureEntities: function (nodes, entityAttribs, callback, extra) {
-        if (Object.prototype.toString.call(entityAttribs) !== '[object Array]') {
-          entityAttribs = [entityAttribs]
-        }
-        if (Object.prototype.toString.call(nodes) !== '[object Array]') {
-          nodes = [nodes]
-        }
-        var q = QDR.queue(self.queueDepth())
-        for (var n=0; n<nodes.length; ++n) {
-          for (var i=0; i<entityAttribs.length; ++i) {
-            var ea = entityAttribs[i]
-            // if we don'e already have the entity or we want to force a refresh
-            if (!self.topology._nodeInfo[nodes[n]][ea.entity] || ea.force)
-              q.defer(self.ensureNodeInfo, nodes[n], ea.entity, ea.attrs || [], q)
-          }
-        }
-        q.await(function (error) {
-          clearTimeout(self.topology._waitTimer)
-          callback(extra);
-        })
-      },
-
-      // queue up a request to get certain attributes for one entity for a node and return the results
-      fetchEntity: function (node, entity, attrs, callback) {
-        var results = {}
-        var gotResponse = function (nodeName, dotentity, response) {
-          results = response
-        }
-        var q = QDR.queue(self.queueDepth())
-        q.defer(self.fetchNodeInfo, node, entity, attrs, q, gotResponse)
-        q.await(function (error) {
-          callback(node, entity, results)
-        })
-      },
-
-      // get/refreshes entities for all topology.nodes
-      // call doneCallback when all data is available
-      // optionally supply a resultCallBack that will be called as each result is avaialble
-      // if a resultCallBack is supplied, the calling function is responsible for accumulating the responses
-      //   otherwise the responses will be returned to the doneCallback as an object
-      fetchAllEntities: function (entityAttribs, doneCallback, resultCallback) {
-        var q = QDR.queue(self.queueDepth())
-        var results = {}
-        if (!resultCallback) {
-          resultCallback = function (nodeName, dotentity, response) {
-            if (!results[nodeName])
-              results[nodeName] = {}
-            results[nodeName][dotentity] = angular.copy(response);
-          }
-        }
-        var gotAResponse = function (nodeName, dotentity, response) {
-          resultCallback(nodeName, dotentity, response)
-        }
-        if (Object.prototype.toString.call(entityAttribs) !== '[object Array]') {
-          entityAttribs = [entityAttribs]
-        }
-        var nodes = Object.keys(self.topology._nodeInfo)
-        for (var n=0; n<nodes.length; ++n) {
-          for (var i=0; i<entityAttribs.length; ++i) {
-            var ea = entityAttribs[i]
-            q.defer(self.fetchNodeInfo, nodes[n], ea.entity, ea.attrs || [], q, gotAResponse)
-          }
-        }
-        q.await(function (error) {
-          doneCallback(results);
-        })
-      },
-
-      setUpdateEntities: function (entities) {
-        self.topology._autoUpdatedEntities = entities
-      },
-      addUpdateEntity: function (entity) {
-        if (self.topology._autoUpdatedEntities.indexOf(entity) == -1)
-          self.topology._autoUpdatedEntities.push(entity)
-      },
-      delUpdateEntity: function (entity) {
-        var index = self.topology._autoUpdatedEntities.indexOf(entity)
-        if (index != -1)
-          self.topology._autoUpdatedEntities.splice(index, 1)
-      },
-
-      /*
-       * send the management messages that build up the topology
-       *
-       *
-       */
-      topology: {
-        _gettingTopo: false,
-        _nodeInfo: {},
-        _lastNodeInfo: {},
-        _waitTimer: null,
-        _getTimer: null,
-        _autoUpdatedEntities: [],
-        q: null,
-
-        nodeInfo: function() {
-          return self.topology._nodeInfo
-        },
-
-        get: function() {
-          if (self.topology._gettingTopo) {
-            QDR.log.debug("asked to get topology but was already getting it")
-            if (self.topology.q)
-              self.topology.q.abort()
-          }
-          self.topology.q = null
-          if (!self.connected) {
-            QDR.log.debug("topology get failed because !self.connected")
-            return;
-          }
-          if (self.topology._getTimer) {
-            clearTimeout(self.topology._getTimer)
-            self.topology._getTimer = null
-          }
-
-          //QDR.log.info("starting get topology with correlator.depth of " + self.correlator.depth())
-          self.topology._gettingTopo = true;
-          self.errorText = undefined;
-
-          // get the list of nodes to query.
-          // once this completes, we will get the info for each node returned
-          self.getRemoteNodeInfo(function(response, context) {
-            if (Object.prototype.toString.call(response) === '[object Array]') {
-              // remove dropped nodes
-              var keys = Object.keys(self.topology._nodeInfo)
-              for (var i=0; i<keys.length; ++i) {
-                if (response.indexOf(keys[i]) < 0) {
-                  delete self.topology._nodeInfo[keys[i]]
-                }
-              }
-              // add any new nodes
-              // if there is only one node, it will not be returned
-              if (response.length === 0) {
-                var parts = self.receiver.remote.attach.source.address.split('/')
-                parts[parts.length-1] = '$management'
-                response.push(parts.join('/'))
-                //QDR.log.info("GET-MGMT-NODES returned an empty list. Using ")
-                //console.dump(response)
-              }
-              for (var i=0; i<response.length; ++i) {
-                if (!angular.isDefined(self.topology._nodeInfo[response[i]])) {
-                  self.topology._nodeInfo[angular.copy(response[i])] = {};
-                }
-              }
-              // also refresh any entities that were requested
-              self.topology.q = QDR.queue(self.queueDepth())
-              for (var i=0; i<self.topology._autoUpdatedEntities.length; ++i) {
-                var entity = self.topology._autoUpdatedEntities[i]
-                //QDR.log.debug("queuing requests for all nodes for " + entity)
-                for (node in self.topology._nodeInfo) {
-                  self.topology.q.defer(self.ensureNodeInfo, node, entity, [], self.topology.q)
-                }
-              }
-              self.topology.q.await(function (error) {
-                self.topology._gettingTopo = false;
-                self.topology.q = null
-                self.topology.ondone(error)
-              })
-            };
-          });
-        },
-
-        cleanUp: function(obj) {
-          if (obj)
-            delete obj;
-        },
-        timedOut: function(q) {
-          // a node dropped out. this happens when the get-mgmt-nodex
-          // results contains more nodes than actually respond within
-          // the timeout
-          QDR.log.debug("timed out waiting for management responses");
-          // note: can't use 'this' in a timeout handler
-          self.topology.miniDump("state at timeout");
-          q.abort()
-          //self.topology.onerror(Error("management responses are not consistent"));
-        },
-
-        addNodeInfo: function(id, entity, values, q) {
-          clearTimeout(self.topology._waitTimer)
-          // save the results in the nodeInfo object
-          if (id) {
-            if (!(id in self.topology._nodeInfo)) {
-              self.topology._nodeInfo[id] = {};
-            }
-            // copy the values to allow garbage collector to reclaim their memory
-            self.topology._nodeInfo[id][entity] = angular.copy(values)
-          }
-          self.topology.cleanUp(values);
-        },
-        ondone: function(waserror) {
-          clearTimeout(self.topology._getTimer);
-          clearTimeout(self.topology._waitTimer);
-          self.topology._waitTimer = null;
-          if (self.updating)
-            self.topology._getTimer = setTimeout(self.topology.get, self.updateInterval);
-          //if (!waserror)
-            self.notifyTopologyDone();
-        },
-        dump: function(prefix) {
-          if (prefix)
-            QDR.log.info(prefix);
-          QDR.log.info("---");
-          for (var key in self.topology._nodeInfo) {
-            QDR.log.info(key);
-            console.dump(self.topology._nodeInfo[key]);
-            QDR.log.info("---");
-          }
-        },
-        miniDump: function(prefix) {
-          if (prefix)
-            QDR.log.info(prefix);
-          QDR.log.info("---");
-          console.dump(Object.keys(self.topology._nodeInfo));
-          QDR.log.info("---");
-        },
-        onerror: function(err) {
-          self.topology._gettingTopo = false;
-          QDR.log.debug("Err:" + err);
-          //self.executeDisconnectActions();
-        }
-
-      },
-      getRemoteNodeInfo: function(callback) {
-        //QDR.log.debug("getRemoteNodeInfo called");
-
-        setTimeout(function () {
-          var ret;
-          // first get the list of remote node names
-          self.correlator.request(
-            ret = self.sendMgmtQuery('GET-MGMT-NODES')
-          ).then(ret.id, function(response, context) {
-            callback(response, context);
-            self.topology.cleanUp(response);
-          }, ret.error);
-        }, 1)
-      },
-
-      // sends a request and updates the topology.nodeInfo object with the response
-      // should only be called from a q.defer() statement
-      ensureNodeInfo: function (nodeId, entity, attrs, q, callback) {
-        //QDR.log.debug("queuing request for " + nodeId + " " + entity)
-        self.getNodeInfo(nodeId, entity, attrs, q, function (nodeName, dotentity, response) {
-          //QDR.log.debug("got response for " + nodeId + " " + entity)
-          self.topology.addNodeInfo(nodeName, dotentity, response, q)
-          callback(null)
-        })
-        return {
-          abort: function() {
-            delete self.topology._nodeInfo[nodeId]
-            //self.topology._nodeInfo[nodeId][entity] = {attributeNames: [], results: [[]]};
-          }
-        }
-      },
-
-      // sends request and returns the response
-      // should only be called from a q.defer() statement
-      fetchNodeInfo: function (nodeId, entity, attrs, q, heartbeat, callback) {
-        self.getNodeInfo(nodeId, entity, attrs, q, function (nodeName, dotentity, response) {
-          heartbeat(nodeName, dotentity, response)
-          callback(null)
-        })
-      },
-
-      getMultipleNodeInfo: function(nodeNames, entity, attrs, callback, selectedNodeId, aggregate) {
-        if (!angular.isDefined(aggregate))
-          aggregate = true;
-        var responses = {};
-        var gotNodesResult = function(nodeName, dotentity, response) {
-          responses[nodeName] = response;
-        }
-
-        var q = QDR.queue(self.queueDepth())
-        nodeNames.forEach(function(id) {
-            q.defer(self.fetchNodeInfo, id, '.' + entity, attrs, q, gotNodesResult)
-        })
-        q.await(function (error) {
-          if (aggregate)
-            self.aggregateNodeInfo(nodeNames, entity, selectedNodeId, responses, callback);
-          else {
-            callback(nodeNames, entity, responses)
-          }
-        })
-      },
-
-      aggregateNodeInfo: function(nodeNames, entity, selectedNodeId, responses, callback) {
-        //QDR.log.debug("got all results for  " + entity);
-        // aggregate the responses
-        var newResponse = {};
-        var thisNode = responses[selectedNodeId];
-        newResponse['attributeNames'] = thisNode.attributeNames;
-        newResponse['results'] = thisNode.results;
-        newResponse['aggregates'] = [];
-        for (var i = 0; i < thisNode.results.length; ++i) {
-          var result = thisNode.results[i];
-          var vals = [];
-          result.forEach(function(val) {
-            vals.push({
-              sum: val,
-              detail: []
-            })
-          })
-          newResponse.aggregates.push(vals);
-        }
-        var nameIndex = thisNode.attributeNames.indexOf("name");
-        var ent = self.schema.entityTypes[entity];
-        var ids = Object.keys(responses);
-        ids.sort();
-        ids.forEach(function(id) {
-          var response = responses[id];
-          var results = response.results;
-          results.forEach(function(result) {
-            // find the matching result in the aggregates
-            var found = newResponse.aggregates.some(function(aggregate, j) {
-              if (aggregate[nameIndex].sum === result[nameIndex]) {
-                // result and aggregate are now the same record, add the graphable values
-                newResponse.attributeNames.forEach(function(key, i) {
-                  if (ent.attributes[key] && ent.attributes[key].graph) {
-                    if (id != selectedNodeId)
-                      aggregate[i].sum += result[i];
-                  }
-                  aggregate[i].detail.push({
-                    node: self.nameFromId(id) + ':',
-                    val: result[i]
-                  })
-                })
-                return true; // stop looping
-              }
-              return false; // continute looking for the aggregate record
-            })
-            if (!found) {
-              // this attribute was not found in the aggregates yet
-              // because it was not in the selectedNodeId's results
-              var vals = [];
-              result.forEach(function(val) {
-                vals.push({
-                  sum: val,
-                  detail: [{
-                    node: self.nameFromId(id),
-                    val: val
-                  }]
-                })
-              })
-              newResponse.aggregates.push(vals)
-            }
-          })
-        })
-        callback(nodeNames, entity, newResponse);
-      },
-
-
-      getSchema: function(callback) {
-        //QDR.log.info("getting schema");
-        var ret;
-        self.correlator.request(
-          ret = self.sendMgmtQuery('GET-SCHEMA')
-        ).then(ret.id, function(response) {
-          //QDR.log.info("Got schema response");
-          // remove deprecated
-          for (var entityName in response.entityTypes) {
-            var entity = response.entityTypes[entityName]
-            if (entity.deprecated) {
-              // deprecated entity
-              delete response.entityTypes[entityName]
-            } else {
-              for (var attributeName in entity.attributes) {
-                var attribute = entity.attributes[attributeName]
-                if (attribute.deprecated) {
-                  // deprecated attribute
-                  delete response.entityTypes[entityName].attributes[attributeName]
-                }
-              }
-            }
-          }
-          self.schema = response;
-          callback()
-        }, ret.error);
-      },
-
-      getNodeInfo: function(nodeName, entity, attrs, q, callback) {
-        //QDR.log.debug("getNodeInfo called with nodeName: " + nodeName + " and entity " + entity);
-        var timedOut = function (q) {
-          q.abort()
-        }
-        var atimer = setTimeout(timedOut, self.timeout * 1000, q);
-        var ret;
-        self.correlator.request(
-          ret = self.sendQuery(nodeName, entity, attrs)
-        ).then(ret.id, function(response) {
-          clearTimeout(atimer)
-          callback(nodeName, entity, response);
-        }, ret.error);
-      },
-
-      sendMethod: function(nodeId, entity, attrs, operation, props, callback) {
-        setTimeout(function () {
-          var ret;
-          self.correlator.request(
-            ret = self._sendMethod(nodeId, entity, attrs, operation, props)
-          ).then(ret.id, function(response, context) {
-            callback(nodeId, entity, response, context);
-          }, ret.error);
-        }, 1)
-      },
-
-      _fullAddr: function(toAddr) {
-        var toAddrParts = toAddr.split('/');
-        if (toAddrParts.shift() != "amqp:") {
-          self.topology.error(Error("unexpected format for router address: " + toAddr));
-          return;
-        }
-        var fullAddr = toAddrParts.join('/');
-        return fullAddr;
-      },
-
-      _sendMethod: function(toAddr, entity, attrs, operation, props) {
-        var ret = {
-          id: self.correlator.corr()
-        };
-        var fullAddr = self._fullAddr(toAddr);
-        if (!self.sender || !self.sendable) {
-          ret.error = "no sender"
-          return ret;
-        }
-        try {
-          var application_properties = {
-            operation: operation
-          }
-          if (entity) {
-            var ent = self.schema.entityTypes[entity];
-            var fullyQualifiedType = ent ? ent.fullyQualifiedType : entity;
-            application_properties.type = fullyQualifiedType || entity;
-          }
-          if (attrs.name)
-            application_properties.name = attrs.name;
-          if (props) {
-            jQuery.extend(application_properties, props);
-          }
-          var msg = {
-            body: attrs,
-            to: fullAddr,
-            reply_to: self.receiver.remote.attach.source.address,
-            correlation_id: ret.id,
-            application_properties: application_properties
-          }
-          self.sender.send(msg);
-          //console.dump("------- method called -------")
-          //console.dump(msg)
-        } catch (e) {
-          error = "error sending: " + e;
-          QDR.log.error(error)
-          ret.error = error;
-        }
-        return ret;
-      },
-
-      sendQuery: function(toAddr, entity, attrs, operation) {
-        operation = operation || "QUERY"
-        var fullAddr = self._fullAddr(toAddr);
-
-        var body;
-        if (attrs) {
-          body = {
-            "attributeNames": attrs,
-          }
-        } else {
-          body = {
-            "attributeNames": [],
-          }
-        }
-        if (entity[0] === '.')
-          entity = entity.substr(1, entity.length - 1)
-        var prefix = "org.apache.qpid.dispatch."
-        var configs = ["address", "autoLink", "linkRoute"]
-        if (configs.indexOf(entity) > -1)
-          prefix += "router.config."
-        return self._send(body, fullAddr, operation, prefix + entity);
-      },
-
-      sendMgmtQuery: function(operation) {
-        return self._send([], "/$management", operation);
-      },
-
-      _send: function(body, to, operation, entityType) {
-        var ret = {
-          id: self.correlator.corr()
-        };
-        if (!self.sender || !self.sendable) {
-          ret.error = "no sender"
-          return ret;
-        }
-        try {
-          var application_properties = {
-            operation: operation,
-            type: "org.amqp.management",
-            name: "self"
-          };
-          if (entityType)
-            application_properties.entityType = entityType;
-
-          self.sender.send({
-            body: body,
-            to: to,
-            reply_to: self.receiver.remote.attach.source.address,
-            correlation_id: ret.id,
-            application_properties: application_properties
-          })
-        } catch (e) {
-          error = "error sending: " + e;
-          QDR.log.error(error)
-          ret.error = error;
-        }
-        return ret;
-      },
-
-      disconnect: function() {
-        self.connection.close();
-        self.connected = false
-        self.errorText = "Disconnected."
-      },
-
-      connectionTimer: null,
-
-      testConnect: function (options, timeout, callback) {
-        var connection;
-        var allowDelete = true;
-        var reconnect = angular.isDefined(options.reconnect) ? options.reconnect : false
-        var baseAddress = options.address + ':' + options.port;
-        var protocol = "ws"
-        if ($location.protocol() === "https")
-          protocol = "wss"
-        QDR.log.info("testConnect called with reconnect " + reconnect + " using " + protocol + " protocol")
-        try {
-          var ws = self.rhea.websocket_connect(WebSocket);
-          var c = {
-            connection_details: ws(protocol + "://" + baseAddress, ["binary"]),
-            reconnect: reconnect,
-            properties: {
-              console_identifier: 'Dispatch console'
-            }
-          };
-          if (options.username && options.username !== '') {
-            c.username = options.username;
-          }
-          if (options.password && options.password !== '') {
... 7806 lines suppressed ...


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org