changeset 1927:b4d3fa26417d

Add vm-compiler plugin base to Thermostat. This is a backport of the vm-compiler plugin from hg/thermostat repository revision fd3632b6449c. This changeset does 'not' compile and relies on the commit ahead: "Complete vm-compiler plugin" which includes the changes to work with this repository. This commit separation is to make it easier to see relevant changes for the vm-compiler plugin. PR3010 Reviewed-by: neugens Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-June/019635.html
author Jie Kang <jkang@redhat.com>
date Wed, 22 Jun 2016 09:04:21 -0400
parents aa8f08ccbd1e
children 07c8d314c3ab
files distribution/assembly/all-plugin-assembly.xml distribution/pom.xml pom.xml vm-compiler/agent/pom.xml vm-compiler/agent/src/main/java/com/redhat/thermostat/vm/compiler/agent/internal/Activator.java vm-compiler/agent/src/main/java/com/redhat/thermostat/vm/compiler/agent/internal/VmCompilerStatBackend.java vm-compiler/agent/src/main/java/com/redhat/thermostat/vm/compiler/agent/internal/VmCompilerStatVmListener.java vm-compiler/agent/src/test/java/com/redhat/thermostat/vm/compiler/agent/internal/ActivatorTest.java vm-compiler/agent/src/test/java/com/redhat/thermostat/vm/compiler/agent/internal/VmClassStatBackendTest.java vm-compiler/agent/src/test/java/com/redhat/thermostat/vm/compiler/agent/internal/VmCompilerStatVmListenerTest.java vm-compiler/client-core/pom.xml vm-compiler/client-core/src/main/java/com/redhat/thermostat/vm/compiler/client/core/VmCompilerStatService.java vm-compiler/client-core/src/main/java/com/redhat/thermostat/vm/compiler/client/core/VmCompilerStatView.java vm-compiler/client-core/src/main/java/com/redhat/thermostat/vm/compiler/client/core/VmCompilerStatViewProvider.java vm-compiler/client-core/src/main/java/com/redhat/thermostat/vm/compiler/client/core/internal/Activator.java vm-compiler/client-core/src/main/java/com/redhat/thermostat/vm/compiler/client/core/internal/VmCompilerStatController.java vm-compiler/client-core/src/main/java/com/redhat/thermostat/vm/compiler/client/core/internal/VmCompilerStatServiceImpl.java vm-compiler/client-core/src/main/java/com/redhat/thermostat/vm/compiler/client/locale/LocaleResources.java vm-compiler/client-core/src/main/resources/com/redhat/thermostat/vm/compiler/client/locale/strings.properties vm-compiler/client-core/src/test/java/com/redhat/thermostat/vm/compiler/client/core/internal/ActivatorTest.java vm-compiler/client-core/src/test/java/com/redhat/thermostat/vm/compiler/client/core/internal/VmCompilerStatControllerTest.java vm-compiler/client-core/src/test/java/com/redhat/thermostat/vm/compiler/client/locale/LocaleResourcesTest.java vm-compiler/client-swing/pom.xml vm-compiler/client-swing/src/main/java/com/redhat/thermostat/vm/compiler/client/swing/internal/Activator.java vm-compiler/client-swing/src/main/java/com/redhat/thermostat/vm/compiler/client/swing/internal/SwingVmCompilerStatView.java vm-compiler/client-swing/src/main/java/com/redhat/thermostat/vm/compiler/client/swing/internal/SwingVmCompilerStatViewProvider.java vm-compiler/client-swing/src/test/java/com/redhat/thermostat/vm/compiler/client/swing/internal/ActivatorTest.java vm-compiler/client-swing/src/test/java/com/redhat/thermostat/vm/compiler/client/swing/internal/SwingVmCompilerStatViewTest.java vm-compiler/common/pom.xml vm-compiler/common/src/main/java/com/redhat/thermostat/vm/compiler/common/ParsedVmCompilerStat.java vm-compiler/common/src/main/java/com/redhat/thermostat/vm/compiler/common/VmCompilerStat.java vm-compiler/common/src/main/java/com/redhat/thermostat/vm/compiler/common/VmCompilerStatDao.java vm-compiler/common/src/main/java/com/redhat/thermostat/vm/compiler/common/internal/Activator.java vm-compiler/common/src/main/java/com/redhat/thermostat/vm/compiler/common/internal/VmCompilerStatCategoryRegistration.java vm-compiler/common/src/main/java/com/redhat/thermostat/vm/compiler/common/internal/VmCompilerStatDaoImpl.java vm-compiler/common/src/main/java/com/redhat/thermostat/vm/compiler/common/internal/VmCompilerStatDaoImplStatementDescriptorRegistration.java vm-compiler/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.CategoryRegistration vm-compiler/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration vm-compiler/common/src/test/java/com/redhat/thermostat/vm/compiler/common/VmCompilerStatTest.java vm-compiler/common/src/test/java/com/redhat/thermostat/vm/compiler/common/internal/ActivatorTest.java vm-compiler/common/src/test/java/com/redhat/thermostat/vm/compiler/common/internal/VmCompilerStatCategoryRegistrationTest.java vm-compiler/common/src/test/java/com/redhat/thermostat/vm/compiler/common/internal/VmCompilerStatDaoImplStatementDescriptorRegistrationTest.java vm-compiler/common/src/test/java/com/redhat/thermostat/vm/compiler/common/internal/VmCompilerStatDaoImplTest.java vm-compiler/distribution/pom.xml vm-compiler/distribution/thermostat-plugin.xml vm-compiler/pom.xml web/war/pom.xml
diffstat 47 files changed, 4090 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/distribution/assembly/all-plugin-assembly.xml	Tue Jun 21 09:25:52 2016 -0400
+++ b/distribution/assembly/all-plugin-assembly.xml	Wed Jun 22 09:04:21 2016 -0400
@@ -72,6 +72,7 @@
         <include>com.redhat.thermostat:thermostat-killvm-distribution</include>
         <include>com.redhat.thermostat:thermostat-vm-numa-distribution</include>
         <include>com.redhat.thermostat:thermostat-vm-io-distribution</include>
+        <include>com.redhat.thermostat:thermostat-vm-compiler-distribution</include>
       </includes>
     </dependencySet>  
   </dependencySets>
--- a/distribution/pom.xml	Tue Jun 21 09:25:52 2016 -0400
+++ b/distribution/pom.xml	Wed Jun 22 09:04:21 2016 -0400
@@ -572,7 +572,12 @@
       <version>${project.version}</version>
       <type>zip</type>
     </dependency>
-
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-compiler-distribution</artifactId>
+      <version>${project.version}</version>
+      <type>zip</type>
+    </dependency>
     <!-- list-categories command -->
     <dependency>
       <groupId>com.redhat.thermostat</groupId>
--- a/pom.xml	Tue Jun 21 09:25:52 2016 -0400
+++ b/pom.xml	Wed Jun 22 09:04:21 2016 -0400
@@ -245,6 +245,7 @@
     <module>numa</module>
     <module>vm-numa</module>
     <module>vm-io</module>
+    <module>vm-compiler</module>
     <module>laf-utils</module>
     <module>thermostat-plugin-validator</module>
     <module>validate-command</module>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/agent/pom.xml	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2012-2016 Red Hat, Inc.
+
+ This file is part of Thermostat.
+
+ Thermostat is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ Thermostat is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Thermostat; see the file COPYING.  If not see
+ <http://www.gnu.org/licenses/>.
+
+ Linking this code with other modules is making a combined work
+ based on this code.  Thus, the terms and conditions of the GNU
+ General Public License cover the whole combination.
+
+ As a special exception, the copyright holders of this code give
+ you permission to link this code with independent modules to
+ produce an executable, regardless of the license terms of these
+ independent modules, and to copy and distribute the resulting
+ executable under terms of your choice, provided that you also
+ meet, for each linked independent module, the terms and conditions
+ of the license of that module.  An independent module is a module
+ which is not derived from or based on this code.  If you modify
+ this code, you may extend this exception to your version of the
+ library, but you are not obligated to do so.  If you do not wish
+ to do so, delete this exception statement from your version.
+
+-->
+<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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>thermostat-vm-compiler</artifactId>
+    <groupId>com.redhat.thermostat</groupId>
+    <version>1.5.8-SNAPSHOT</version>
+  </parent>
+  <artifactId>thermostat-vm-compiler-agent</artifactId>
+  <packaging>bundle</packaging>
+  <name>Thermostat VM Compiler Agent plugin</name>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-SymbolicName>com.redhat.thermostat.vm.compiler.agent</Bundle-SymbolicName>
+            <Bundle-Activator>com.redhat.thermostat.vm.compiler.agent.internal.Activator</Bundle-Activator>
+            <Export-Package />
+            <Private-Package>
+              com.redhat.thermostat.vm.compiler.agent.internal
+            </Private-Package>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-compiler-common</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-agent-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-storage-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-test</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/agent/src/main/java/com/redhat/thermostat/vm/compiler/agent/internal/Activator.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.agent.internal;
+
+import java.util.Map;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+import com.redhat.thermostat.agent.VmStatusListenerRegistrar;
+import com.redhat.thermostat.backend.Backend;
+import com.redhat.thermostat.backend.BackendService;
+import com.redhat.thermostat.common.MultipleServiceTracker;
+import com.redhat.thermostat.common.MultipleServiceTracker.Action;
+import com.redhat.thermostat.common.Version;
+import com.redhat.thermostat.storage.core.WriterID;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+
+public class Activator implements BundleActivator {
+
+    private MultipleServiceTracker tracker;
+    private VmCompilerStatBackend backend;
+    private ServiceRegistration<Backend> reg;
+
+    @Override
+    public void start(final BundleContext context) throws Exception {
+
+        final VmStatusListenerRegistrar registrar = new VmStatusListenerRegistrar(context);
+
+        Class<?>[] deps = new Class<?>[] {
+                BackendService.class,
+                VmCompilerStatDao.class,
+                WriterID.class, // vm compiler uses it
+        };
+        tracker = new MultipleServiceTracker(context, deps, new Action() {
+
+            @Override
+            public void dependenciesAvailable(Map<String, Object> services) {
+                VmCompilerStatDao vmCompilerStatDao = (VmCompilerStatDao) services.get(VmCompilerStatDao.class.getName());
+                Version version = new Version(context.getBundle());
+                WriterID id = (WriterID) services.get(WriterID.class.getName());
+                backend = new VmCompilerStatBackend(vmCompilerStatDao, version, registrar, id);
+                reg = context.registerService(Backend.class, backend, null);
+            }
+
+            @Override
+            public void dependenciesUnavailable() {
+                if (backend.isActive()) {
+                    backend.deactivate();
+                }
+                reg.unregister();
+            }
+        });
+        tracker.open();
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        tracker.close();
+    }
+
+    /*
+     * For testing purposes only.
+     */
+    VmCompilerStatBackend getBackend() {
+        return backend;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/agent/src/main/java/com/redhat/thermostat/vm/compiler/agent/internal/VmCompilerStatBackend.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.agent.internal;
+
+import com.redhat.thermostat.agent.VmStatusListenerRegistrar;
+import com.redhat.thermostat.backend.VmListenerBackend;
+import com.redhat.thermostat.backend.VmUpdateListener;
+import com.redhat.thermostat.common.Version;
+import com.redhat.thermostat.storage.core.WriterID;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+
+public class VmCompilerStatBackend extends VmListenerBackend {
+
+    private final VmCompilerStatDao vmCompilerStats;
+
+    public VmCompilerStatBackend(VmCompilerStatDao vmCompilerStatDao, Version version,
+            VmStatusListenerRegistrar registrar, WriterID writerId) {
+        super("VM Compiler Backend",
+              "Gathers compiler statistics about a JVM",
+              "Red Hat, Inc.", version.getVersionNumber(), true, registrar, writerId);
+        this.vmCompilerStats = vmCompilerStatDao;
+    }
+
+    @Override
+    public int getOrderValue() {
+        return ORDER_CODE_GROUP;
+    }
+
+    @Override
+    protected VmUpdateListener createVmListener(String writerId, String vmId, int pid) {
+        return new VmCompilerStatVmListener(writerId, vmCompilerStats, vmId);
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/agent/src/main/java/com/redhat/thermostat/vm/compiler/agent/internal/VmCompilerStatVmListener.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.agent.internal;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.redhat.thermostat.backend.VmUpdate;
+import com.redhat.thermostat.backend.VmUpdateException;
+import com.redhat.thermostat.backend.VmUpdateListener;
+import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStat;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+
+class VmCompilerStatVmListener implements VmUpdateListener {
+
+    private static final Logger logger = LoggingUtils.getLogger(VmCompilerStatVmListener.class);
+
+    private final VmCompilerStatDao dao;
+    private final String vmId;
+    private final String writerId;
+
+    private boolean error;
+
+    VmCompilerStatVmListener(String writerId, VmCompilerStatDao dao, String vmId) {
+        this.dao = dao;
+        this.vmId = vmId;
+        this.writerId = writerId;
+    }
+
+    @Override
+    public void countersUpdated(VmUpdate update) {
+        try {
+            long totalCompiles = longValueOrUnknown(update, "totalCompiles", vmId);
+            long totalBailouts = longValueOrUnknown(update, "totalBailouts", vmId);
+            long totalInvalidates = longValueOrUnknown(update, "totalInvalidates", vmId);
+            long compilationTime = update.getPerformanceCounterLong("java.ci.totalTime") / update.getPerformanceCounterLong("sun.os.hrt.frequency");
+            long lastSize = longValueOrUnknown(update, "lastSize", vmId);
+            long lastType = longValueOrUnknown(update, "lastType", vmId);
+            String lastMethod = update.getPerformanceCounterString("sun.ci.lastMethod");
+            long lastFailedType = longValueOrUnknown(update, "lastFailedType", vmId);
+            String lastFailedMethod = update.getPerformanceCounterString("sun.ci.lastFailedMethod");
+
+            long timestamp = System.currentTimeMillis();
+            VmCompilerStat stat = new VmCompilerStat(writerId, vmId, timestamp,
+                    totalCompiles, totalBailouts, totalInvalidates,
+                    compilationTime,
+                    lastSize, lastType, lastMethod,
+                    lastFailedType, lastFailedMethod);
+
+            dao.putVmCompilerStat(stat);
+
+        } catch (VmUpdateException e) {
+            logger.log(Level.WARNING, "Error gathering class info for VM " + vmId, e);
+        }
+    }
+
+    private long longValueOrUnknown(VmUpdate update, String name, String vmId) throws VmUpdateException {
+        String fullName = "sun.ci." + name;
+        Long value = update.getPerformanceCounterLong(fullName);
+        if (value == null) {
+            logWarningOnce("Unable to determine " + fullName + " for VM " + vmId);
+        }
+        return value == null ? VmCompilerStat.UNKNOWN : value;
+    }
+
+    private void logWarningOnce(String message) {
+        if (!error) {
+            logger.log(Level.WARNING, message);
+            logger.log(Level.WARNING, "Further warnings will be ignored");
+            error = true;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/agent/src/test/java/com/redhat/thermostat/vm/compiler/agent/internal/ActivatorTest.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.agent.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+
+import com.redhat.thermostat.backend.Backend;
+import com.redhat.thermostat.backend.BackendService;
+import com.redhat.thermostat.storage.core.WriterID;
+import com.redhat.thermostat.testutils.StubBundleContext;
+import com.redhat.thermostat.vm.compiler.agent.internal.Activator;
+import com.redhat.thermostat.vm.compiler.agent.internal.VmCompilerStatBackend;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+
+public class ActivatorTest {
+
+    @Test
+    public void verifyActivatorDoesNotRegisterServiceOnMissingDeps() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        assertEquals(0, context.getAllServices().size());
+        assertEquals(3, context.getServiceListeners().size());
+
+        activator.stop(context);
+    }
+
+    @Test
+    public void verifyActivatorRegistersServices() throws Exception {
+        StubBundleContext context = new StubBundleContext() {
+            @Override
+            public Bundle getBundle() {
+                Bundle result = mock(Bundle.class);
+                when(result.getVersion()).thenReturn(Version.emptyVersion);
+                return result;
+            }
+        };
+        BackendService service = mock(BackendService.class);
+        VmCompilerStatDao vmCompilerStatDao = mock(VmCompilerStatDao.class);
+        WriterID idService = mock(WriterID.class);
+
+        context.registerService(BackendService.class, service, null);
+        context.registerService(VmCompilerStatDao.class, vmCompilerStatDao, null);
+        context.registerService(WriterID.class, idService, null);
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        assertTrue(context.isServiceRegistered(Backend.class.getName(), VmCompilerStatBackend.class));
+        VmCompilerStatBackend backend = activator.getBackend();
+        assertNotNull(backend);
+
+        // something in core thermostat activates the backend; do it manually here
+        backend.activate();
+
+        activator.stop(context);
+
+        assertFalse(backend.isActive());
+
+        assertEquals(0, context.getServiceListeners().size());
+        assertEquals(3, context.getAllServices().size());
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/agent/src/test/java/com/redhat/thermostat/vm/compiler/agent/internal/VmClassStatBackendTest.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.agent.internal;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.redhat.thermostat.agent.VmStatusListenerRegistrar;
+import com.redhat.thermostat.common.Ordered;
+import com.redhat.thermostat.common.Version;
+import com.redhat.thermostat.storage.core.WriterID;
+import com.redhat.thermostat.vm.compiler.agent.internal.VmCompilerStatBackend;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+
+public class VmClassStatBackendTest {
+
+    private VmCompilerStatBackend backend;
+
+    @Before
+    public void setup() {
+        VmCompilerStatDao vmCompilerStatDao = mock(VmCompilerStatDao.class);
+
+        Version version = mock(Version.class);
+        when(version.getVersionNumber()).thenReturn("0.0.0");
+
+        VmStatusListenerRegistrar registrar = mock(VmStatusListenerRegistrar.class);
+
+        WriterID id = mock(WriterID.class);
+        backend = new VmCompilerStatBackend(vmCompilerStatDao, version, registrar, id);
+    }
+
+    @Test
+    public void testOrderValue() {
+        int orderValue = backend.getOrderValue();
+        assertTrue(orderValue >= Ordered.ORDER_CODE_GROUP);
+        assertTrue(orderValue < Ordered.ORDER_USER_GROUP);
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/agent/src/test/java/com/redhat/thermostat/vm/compiler/agent/internal/VmCompilerStatVmListenerTest.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.agent.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import com.redhat.thermostat.backend.VmUpdate;
+import com.redhat.thermostat.backend.VmUpdateException;
+import com.redhat.thermostat.vm.compiler.agent.internal.VmCompilerStatVmListener;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStat;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+
+public class VmCompilerStatVmListenerTest {
+
+    private static final String VM_ID = "vmId";
+    private static final Long COMPILER_TIME_TICKS = 4242L;
+    private static final Long FREQUENCY = 2L;
+    private static final Long COMPILATION_TIME = COMPILER_TIME_TICKS / FREQUENCY;
+
+    private VmCompilerStatDao dao;
+    private VmCompilerStatVmListener listener;
+
+    private VmUpdate update;
+
+    @Before
+    public void setUp() throws VmUpdateException {
+        dao = mock(VmCompilerStatDao.class);
+        listener = new VmCompilerStatVmListener("foo-agent", dao, VM_ID);
+
+        update = mock(VmUpdate.class);
+
+        when(update.getPerformanceCounterLong("java.ci.totalTime")).thenReturn(COMPILER_TIME_TICKS);
+        when(update.getPerformanceCounterLong("sun.os.hrt.frequency")).thenReturn(FREQUENCY);
+    }
+
+    @Test
+    public void testMonitorUpdatedCompilerStat() throws Exception {
+        listener.countersUpdated(update);
+
+        ArgumentCaptor<VmCompilerStat> arg = ArgumentCaptor.forClass(VmCompilerStat.class);
+        verify(dao).putVmCompilerStat(arg.capture());
+        VmCompilerStat stat = arg.getValue();
+        assertEquals(COMPILATION_TIME, (Long) stat.getCompilationTime());
+        assertEquals(VM_ID, stat.getVmId());
+    }
+
+    @Test
+    public void testMonitorUpdatedCompilerStatTwice() throws Exception {
+        listener.countersUpdated(update);
+        listener.countersUpdated(update);
+
+        // This checks a bug where the Category threw an IllegalStateException because the DAO
+        // created a new one on each call, thus violating the unique guarantee of Category.
+    }
+
+    @Test
+    public void testMonitorUpdateFails() throws VmUpdateException {
+        when(update.getPerformanceCounterLong(anyString())).thenThrow(new VmUpdateException());
+        listener.countersUpdated(update);
+
+        verifyNoMoreInteractions(dao);
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-core/pom.xml	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2012-2016 Red Hat, Inc.
+
+ This file is part of Thermostat.
+
+ Thermostat is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ Thermostat is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Thermostat; see the file COPYING.  If not see
+ <http://www.gnu.org/licenses/>.
+
+ Linking this code with other modules is making a combined work
+ based on this code.  Thus, the terms and conditions of the GNU
+ General Public License cover the whole combination.
+
+ As a special exception, the copyright holders of this code give
+ you permission to link this code with independent modules to
+ produce an executable, regardless of the license terms of these
+ independent modules, and to copy and distribute the resulting
+ executable under terms of your choice, provided that you also
+ meet, for each linked independent module, the terms and conditions
+ of the license of that module.  An independent module is a module
+ which is not derived from or based on this code.  If you modify
+ this code, you may extend this exception to your version of the
+ library, but you are not obligated to do so.  If you do not wish
+ to do so, delete this exception statement from your version.
+
+-->
+<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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>thermostat-vm-compiler</artifactId>
+    <groupId>com.redhat.thermostat</groupId>
+    <version>1.5.8-SNAPSHOT</version>
+  </parent>
+  <artifactId>thermostat-vm-compiler-client-core</artifactId>
+  <packaging>bundle</packaging>
+  <name>Thermostat VM Compiler Core Client plugin</name>
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>true</filtering>
+        <excludes>
+          <exclude>**/*.png</exclude>
+        </excludes>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>false</filtering>
+        <includes>
+          <include>**/*.png</include>
+        </includes>
+      </resource>
+    </resources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-SymbolicName>com.redhat.thermostat.vm.compiler.client.core</Bundle-SymbolicName>
+            <Bundle-Activator>com.redhat.thermostat.vm.compiler.client.core.internal.Activator</Bundle-Activator>
+            <Export-Package>
+              com.redhat.thermostat.vm.compiler.client.core,
+              com.redhat.thermostat.vm.compiler.client.locale
+            </Export-Package>
+            <Private-Package>
+              com.redhat.thermostat.vm.compiler.client.core.internal
+            </Private-Package>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-compiler-common</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-test</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-core/src/main/java/com/redhat/thermostat/vm/compiler/client/core/VmCompilerStatService.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.client.core;
+
+import com.redhat.thermostat.client.core.InformationService;
+import com.redhat.thermostat.storage.core.VmRef;
+
+public interface VmCompilerStatService extends InformationService<VmRef> {
+
+    public static final String SERVICE_ID = "com.redhat.thermostat.vm.compiler";
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-core/src/main/java/com/redhat/thermostat/vm/compiler/client/core/VmCompilerStatView.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.client.core;
+
+import java.util.List;
+
+import com.redhat.thermostat.client.core.views.BasicView;
+import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.common.Duration;
+import com.redhat.thermostat.common.model.Range;
+import com.redhat.thermostat.shared.locale.LocalizedString;
+import com.redhat.thermostat.shared.locale.Translate;
+import com.redhat.thermostat.storage.model.DiscreteTimeData;
+import com.redhat.thermostat.vm.compiler.client.locale.LocaleResources;
+
+public abstract class VmCompilerStatView extends BasicView implements UIComponent {
+
+    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
+
+    public enum Type {
+        TOTAL_COMPILES(LocaleResources.STATS_TOTAL_COMPILES),
+        TOTAL_INVALIDATES(LocaleResources.STATS_TOTAL_INVALIDATES),
+        TOTAL_BAILOUTS(LocaleResources.STATS_TOTAL_BAILOUTS),
+
+        TOTAL_TIME(LocaleResources.STATS_COMPILATION_TIME),
+        ;
+
+        private final LocalizedString label;
+
+        Type(LocaleResources resource) {
+            this.label = t.localize(resource);
+        }
+
+        public LocalizedString getLabel() {
+            return this.label;
+        }
+    }
+
+    public static class ViewData {
+        public String totalCompiles;
+        public String totalBailouts;
+        public String totalInvalidates;
+        public String compilationTime;
+        public String lastSize;
+        public String lastType;
+        public String lastMethod;
+        public String lastFailedType;
+        public String lastFailedMethod;
+    }
+
+    public abstract void setCurrentDisplay(ViewData stat);
+
+    public abstract Duration getUserDesiredDuration();
+    public abstract void setAvailableDataRange(Range<Long> availableDataRange);
+
+    public abstract void addCompilerData(Type type, List<DiscreteTimeData<? extends Number>> data);
+    public abstract void clearCompilerData(Type type);
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-core/src/main/java/com/redhat/thermostat/vm/compiler/client/core/VmCompilerStatViewProvider.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.client.core;
+
+import com.redhat.thermostat.annotations.ExtensionPoint;
+import com.redhat.thermostat.client.core.views.ViewProvider;
+
+@ExtensionPoint
+public interface VmCompilerStatViewProvider extends ViewProvider {
+
+    @Override
+    public VmCompilerStatView createView();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-core/src/main/java/com/redhat/thermostat/vm/compiler/client/core/internal/Activator.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.client.core.internal;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Objects;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+import com.redhat.thermostat.client.core.InformationService;
+import com.redhat.thermostat.common.ApplicationService;
+import com.redhat.thermostat.common.Constants;
+import com.redhat.thermostat.common.MultipleServiceTracker;
+import com.redhat.thermostat.common.MultipleServiceTracker.Action;
+import com.redhat.thermostat.storage.core.VmRef;
+import com.redhat.thermostat.vm.compiler.client.core.VmCompilerStatService;
+import com.redhat.thermostat.vm.compiler.client.core.VmCompilerStatViewProvider;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+
+public class Activator implements BundleActivator {
+
+    private MultipleServiceTracker tracker;
+    private ServiceRegistration reg;
+
+    @Override
+    public void start(final BundleContext context) throws Exception {
+        Class<?>[] deps = new Class<?>[] {
+            ApplicationService.class,
+            VmCompilerStatDao.class,
+            VmCompilerStatViewProvider.class
+        };
+
+        tracker = new MultipleServiceTracker(context, deps, new Action() {
+
+            @Override
+            public void dependenciesAvailable(Map<String, Object> services) {
+                VmCompilerStatDao dao = (VmCompilerStatDao) services.get(VmCompilerStatDao.class.getName());
+                Objects.requireNonNull(dao);
+                ApplicationService appSvc = (ApplicationService) services.get(ApplicationService.class.getName());
+                Objects.requireNonNull(appSvc);
+                VmCompilerStatViewProvider viewProvider = (VmCompilerStatViewProvider) services.get(VmCompilerStatViewProvider.class.getName());
+                Objects.requireNonNull(viewProvider);
+
+                VmCompilerStatService service = new VmCompilerStatServiceImpl(appSvc, dao, viewProvider);
+                Dictionary<String, String> properties = new Hashtable<>();
+                properties.put(Constants.GENERIC_SERVICE_CLASSNAME, VmRef.class.getName());
+                properties.put(InformationService.KEY_SERVICE_ID, VmCompilerStatService.SERVICE_ID);
+                reg = context.registerService(InformationService.class.getName(), service, properties);
+            }
+
+            @Override
+            public void dependenciesUnavailable() {
+                reg.unregister();
+            }
+
+        });
+        tracker.open();
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        tracker.close();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-core/src/main/java/com/redhat/thermostat/vm/compiler/client/core/internal/VmCompilerStatController.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.client.core.internal;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import com.redhat.thermostat.client.core.controllers.InformationServiceController;
+import com.redhat.thermostat.client.core.experimental.TimeRangeController;
+import com.redhat.thermostat.client.core.views.BasicView.Action;
+import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.ApplicationService;
+import com.redhat.thermostat.common.Duration;
+import com.redhat.thermostat.common.NotImplementedException;
+import com.redhat.thermostat.common.Timer;
+import com.redhat.thermostat.common.Timer.SchedulingType;
+import com.redhat.thermostat.common.model.Range;
+import com.redhat.thermostat.shared.locale.LocalizedString;
+import com.redhat.thermostat.shared.locale.Translate;
+import com.redhat.thermostat.storage.core.VmRef;
+import com.redhat.thermostat.storage.model.DiscreteTimeData;
+import com.redhat.thermostat.vm.compiler.client.core.VmCompilerStatView;
+import com.redhat.thermostat.vm.compiler.client.core.VmCompilerStatView.ViewData;
+import com.redhat.thermostat.vm.compiler.client.core.VmCompilerStatViewProvider;
+import com.redhat.thermostat.vm.compiler.client.locale.LocaleResources;
+import com.redhat.thermostat.vm.compiler.common.ParsedVmCompilerStat;
+import com.redhat.thermostat.vm.compiler.common.ParsedVmCompilerStat.CompileType;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStat;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+
+public class VmCompilerStatController implements InformationServiceController<VmRef> {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private static final Map<CompileType, String> COMPILATION_TYPES = new HashMap<>();
+    private static final Map<CompileType, String> FAILED_COMPILATION_TYPES = new HashMap<>();
+
+    static {
+        COMPILATION_TYPES.put(CompileType.NO_COMPILE,
+                translator.localize(LocaleResources.COMPILE_TYPE_NO_COMPILE).getContents());
+        COMPILATION_TYPES.put(CompileType.NORMAL_COMPILE,
+                translator.localize(LocaleResources.COMPILE_TYPE_NORMAL_COMPILE).getContents());
+        COMPILATION_TYPES.put(CompileType.OSR_COMPILE,
+                translator.localize(LocaleResources.COMPILE_TYPE_OSR_COMPILE).getContents());
+        COMPILATION_TYPES.put(CompileType.NATIVE_COMPILE,
+                translator.localize(LocaleResources.COMPILE_TYPE_NATIVE_COMPILE).getContents());
+
+        FAILED_COMPILATION_TYPES.put(CompileType.NO_COMPILE,
+                translator.localize(LocaleResources.COMPILE_TYPE_NO_FAILED_COMPILE).getContents());
+        FAILED_COMPILATION_TYPES.put(CompileType.NORMAL_COMPILE,
+                translator.localize(LocaleResources.COMPILE_TYPE_NORMAL_COMPILE).getContents());
+        FAILED_COMPILATION_TYPES.put(CompileType.OSR_COMPILE,
+                translator.localize(LocaleResources.COMPILE_TYPE_OSR_COMPILE).getContents());
+        FAILED_COMPILATION_TYPES.put(CompileType.NATIVE_COMPILE,
+                translator.localize(LocaleResources.COMPILE_TYPE_NATIVE_COMPILE).getContents());
+    }
+
+    private final VmCompilerStatView compilerView;
+    private final VmRef ref;
+    private final VmCompilerStatDao dao;
+    private final Timer timer;
+
+    private TimeRangeController<VmCompilerStat, VmRef> timeRangeController;
+
+    public VmCompilerStatController(ApplicationService appSvc, VmCompilerStatDao vmCompilerStatDao, VmRef ref, VmCompilerStatViewProvider viewProvider) {
+        this.ref = ref;
+        dao = vmCompilerStatDao;
+        timer = appSvc.getTimerFactory().createTimer();
+
+        timer.setAction(new UpdateChartData());
+        timer.setSchedulingType(SchedulingType.FIXED_RATE);
+        timer.setTimeUnit(TimeUnit.SECONDS);
+        timer.setDelay(5);
+        timer.setInitialDelay(0);
+
+        compilerView = viewProvider.createView();
+
+        compilerView.addActionListener(new ActionListener<VmCompilerStatView.Action>() {
+            @Override
+            public void actionPerformed(ActionEvent<Action> actionEvent) {
+                switch(actionEvent.getActionId()) {
+                    case HIDDEN:
+                        stop();
+                        break;
+                    case VISIBLE:
+                        start();
+                        break;
+                    default:
+                        throw new NotImplementedException("unknown action: " + actionEvent.getActionId());
+                }
+            }
+        });
+
+
+        timeRangeController = new TimeRangeController<>();
+    }
+
+    private void start() {
+        timer.start();
+    }
+
+    private void stop() {
+        timer.stop();
+    }
+
+    @Override
+    public LocalizedString getLocalizedName() {
+        return translator.localize(LocaleResources.VM_INFO_TAB_COMPILER);
+    }
+
+    @Override
+    public UIComponent getView() {
+        return (UIComponent) compilerView;
+    }
+
+    private class UpdateChartData implements Runnable {
+        @Override
+        public void run() {
+            VmCompilerStat oldest = dao.getOldest(ref);
+            VmCompilerStat newest = dao.getNewest(ref);
+            // Do nothing when there is no data
+            if (oldest == null || newest == null) {
+                return;
+            }
+
+            ParsedVmCompilerStat stat = new ParsedVmCompilerStat(newest);
+
+            ViewData data = new ViewData();
+            data.totalCompiles = String.valueOf(stat.getTotalCompiles());
+            data.totalBailouts = String.valueOf(stat.getTotalBailouts());
+            data.totalInvalidates = String.valueOf(stat.getTotalInvalidates());
+            data.compilationTime = String.format("%d %s", stat.getCompilationTime().asMilliseconds(), "ms");
+            data.lastSize = stat.getLastSize().toString();
+            data.lastType = translateCompileDescription(stat.getLastType());
+            data.lastMethod = stat.getLastMethod();
+            data.lastFailedType = translateDecompileDescription(stat.getLastFailedType());
+            data.lastFailedMethod = stat.getLastFailedMethod();
+
+            compilerView.setCurrentDisplay(data);
+
+            final List<DiscreteTimeData<? extends Number>> totalCompiles = new ArrayList<>();
+            final List<DiscreteTimeData<? extends Number>> totalInvalidates = new ArrayList<>();
+            final List<DiscreteTimeData<? extends Number>> totalBailouts = new ArrayList<>();
+            final List<DiscreteTimeData<? extends Number>> compileTime = new ArrayList<>();
+
+            Range<Long> newAvailableRange = new Range<>(oldest.getTimeStamp(), newest.getTimeStamp());
+
+            TimeRangeController.StatsSupplier<VmCompilerStat, VmRef> singleValueSupplier = new TimeRangeController.StatsSupplier<VmCompilerStat, VmRef>() {
+                @Override
+                public List<VmCompilerStat> getStats(final VmRef ref, final long since, final long to) {
+                    return dao.getCompilerStats(ref, since, to);
+                }
+            };
+
+            TimeRangeController.SingleArgRunnable<VmCompilerStat> runnable = new TimeRangeController.SingleArgRunnable<VmCompilerStat>() {
+                @Override
+                public void run(VmCompilerStat stat) {
+                    long timeStamp = stat.getTimeStamp();
+
+                    totalCompiles.add(new DiscreteTimeData<Number>(timeStamp, stat.getTotalCompiles()));
+                    totalInvalidates.add(new DiscreteTimeData<Number>(timeStamp, stat.getTotalInvalidates()));
+                    totalBailouts.add(new DiscreteTimeData<Number>(timeStamp, stat.getTotalBailouts()));
+
+                    compileTime.add(new DiscreteTimeData<Number>(timeStamp, stat.getCompilationTime()));
+                }
+
+            };
+
+            Duration userDesiredDuration = compilerView.getUserDesiredDuration();
+            if (userDesiredDuration != null) {
+                timeRangeController.update(userDesiredDuration, newAvailableRange, singleValueSupplier, ref, runnable);
+                compilerView.setAvailableDataRange(timeRangeController.getAvailableRange());
+
+                compilerView.addCompilerData(VmCompilerStatView.Type.TOTAL_COMPILES, totalCompiles);
+                compilerView.addCompilerData(VmCompilerStatView.Type.TOTAL_BAILOUTS, totalBailouts);
+                compilerView.addCompilerData(VmCompilerStatView.Type.TOTAL_INVALIDATES, totalInvalidates);
+
+                compilerView.addCompilerData(VmCompilerStatView.Type.TOTAL_TIME, compileTime);
+            }
+        }
+
+        private String translateCompileDescription(CompileType type) {
+            return COMPILATION_TYPES.get(type);
+        }
+
+        private String translateDecompileDescription(CompileType type) {
+            return FAILED_COMPILATION_TYPES.get(type);
+        }
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-core/src/main/java/com/redhat/thermostat/vm/compiler/client/core/internal/VmCompilerStatServiceImpl.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.client.core.internal;
+
+import com.redhat.thermostat.client.core.NameMatchingRefFilter;
+import com.redhat.thermostat.client.core.controllers.InformationServiceController;
+import com.redhat.thermostat.common.ApplicationService;
+import com.redhat.thermostat.common.Filter;
+import com.redhat.thermostat.storage.core.VmRef;
+import com.redhat.thermostat.vm.compiler.client.core.VmCompilerStatService;
+import com.redhat.thermostat.vm.compiler.client.core.VmCompilerStatViewProvider;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+
+public class VmCompilerStatServiceImpl implements VmCompilerStatService {
+
+    private static final int ORDER = ORDER_CODE_GROUP;
+    private Filter<VmRef> filter = new NameMatchingRefFilter<>();
+
+    private ApplicationService appSvc;
+    private VmCompilerStatDao vmCompilerStatDao;
+    private VmCompilerStatViewProvider viewProvider;
+
+    public VmCompilerStatServiceImpl(ApplicationService appSvc,
+            VmCompilerStatDao vmCompilerStatDao, VmCompilerStatViewProvider viewProvider) {
+        this.appSvc = appSvc;
+        this.vmCompilerStatDao = vmCompilerStatDao;
+        this.viewProvider = viewProvider;
+    }
+
+    @Override
+    public InformationServiceController<VmRef> getInformationServiceController(VmRef ref) {
+        return new VmCompilerStatController(appSvc, vmCompilerStatDao, ref, viewProvider);
+    }
+
+    @Override
+    public Filter<VmRef> getFilter() {
+        return filter;
+    }
+
+    @Override
+    public int getOrderValue() {
+        return ORDER;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-core/src/main/java/com/redhat/thermostat/vm/compiler/client/locale/LocaleResources.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.client.locale;
+
+import com.redhat.thermostat.shared.locale.Translate;
+
+public enum LocaleResources {
+
+    VM_INFO_TAB_COMPILER,
+    VM_COMPILER_HEADER,
+
+    STATS_TABLE_COLUMN_NAME,
+    STATS_TABLE_COLUMN_VALUE,
+
+    STAT_CHART_NUMBER_AXIS,
+    STAT_CHART_TIME_AXIS,
+
+    STATS_TOTAL_COMPILES,
+    STATS_TOTAL_BAILOUTS,
+    STATS_TOTAL_INVALIDATES,
+    STATS_COMPILATION_TIME,
+    STATS_LAST_SIZE,
+    STATS_LAST_TYPE,
+    STATS_LAST_METHOD,
+    STATS_LAST_FAILED_TYPE,
+    STATS_LAST_FAILED_METHOD,
+
+    COMPILE_TYPE_NO_COMPILE,
+    COMPILE_TYPE_NO_FAILED_COMPILE,
+    COMPILE_TYPE_NORMAL_COMPILE,
+    COMPILE_TYPE_OSR_COMPILE,
+    COMPILE_TYPE_NATIVE_COMPILE,
+
+    ;
+
+    public static final String RESOURCE_BUNDLE =
+            "com.redhat.thermostat.vm.compiler.client.locale.strings";
+
+    public static Translate<LocaleResources> createLocalizer() {
+        return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-core/src/main/resources/com/redhat/thermostat/vm/compiler/client/locale/strings.properties	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,26 @@
+VM_INFO_TAB_COMPILER = Compiler
+VM_COMPILER_HEADER = Compiler Statistics
+
+STATS_TABLE_COLUMN_NAME = Name
+STATS_TABLE_COLUMN_VALUE = Value
+
+STAT_CHART_NUMBER_AXIS = Number
+STAT_CHART_TIME_AXIS = Time (ms)
+
+STATS_TOTAL_COMPILES = Total Compiles
+STATS_TOTAL_BAILOUTS = Total Bailouts
+STATS_TOTAL_INVALIDATES = Total Invalidates
+STATS_COMPILATION_TIME = Total Compilation Time
+STATS_LAST_SIZE = Size of Code Last Compiled
+STATS_LAST_TYPE = Type of Last Compiled
+STATS_LAST_METHOD = Last Method Compiled
+STATS_LAST_FAILED_TYPE = Type of Last Failed
+STATS_LAST_FAILED_METHOD = Last Failed Method
+
+COMPILE_TYPE_NO_COMPILE = No Compile
+COMPILE_TYPE_NO_FAILED_COMPILE = No Failed Compiles
+COMPILE_TYPE_NORMAL_COMPILE = Normal Compile
+COMPILE_TYPE_OSR_COMPILE = OSR Compile
+COMPILE_TYPE_NATIVE_COMPILE = Native Compile
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-core/src/test/java/com/redhat/thermostat/vm/compiler/client/core/internal/ActivatorTest.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.client.core.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.client.core.InformationService;
+import com.redhat.thermostat.common.ApplicationService;
+import com.redhat.thermostat.testutils.StubBundleContext;
+import com.redhat.thermostat.vm.compiler.client.core.VmCompilerStatViewProvider;
+import com.redhat.thermostat.vm.compiler.client.core.internal.Activator;
+import com.redhat.thermostat.vm.compiler.client.core.internal.VmCompilerStatServiceImpl;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+
+public class ActivatorTest {
+
+    @Test
+    public void verifyActivatorDoesNotRegisterServiceOnMissingDeps() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        assertEquals(0, context.getAllServices().size());
+        assertNotSame(1, context.getServiceListeners().size());
+
+        activator.stop(context);
+
+        assertEquals(0, context.getServiceListeners().size());
+    }
+
+    @Test
+    public void verifyActivatorRegistersServices() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+        ApplicationService appService = mock(ApplicationService.class);
+        VmCompilerStatDao daoService = mock(VmCompilerStatDao.class);
+        VmCompilerStatViewProvider viewProvider = mock(VmCompilerStatViewProvider.class);
+
+        context.registerService(ApplicationService.class, appService, null);
+        context.registerService(VmCompilerStatDao.class, daoService, null);
+        context.registerService(VmCompilerStatViewProvider.class, viewProvider, null);
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        assertTrue(context.isServiceRegistered(InformationService.class.getName(), VmCompilerStatServiceImpl.class));
+
+        activator.stop(context);
+
+        assertEquals(0, context.getServiceListeners().size());
+        assertEquals(3, context.getAllServices().size());
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-core/src/test/java/com/redhat/thermostat/vm/compiler/client/core/internal/VmCompilerStatControllerTest.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.client.core.internal;
+
+import static org.mockito.Matchers.isA;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import com.redhat.thermostat.client.core.views.BasicView.Action;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.ApplicationService;
+import com.redhat.thermostat.common.Timer;
+import com.redhat.thermostat.common.TimerFactory;
+import com.redhat.thermostat.storage.core.VmRef;
+import com.redhat.thermostat.vm.compiler.client.core.VmCompilerStatView;
+import com.redhat.thermostat.vm.compiler.client.core.VmCompilerStatView.ViewData;
+import com.redhat.thermostat.vm.compiler.client.core.VmCompilerStatViewProvider;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStat;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+
+public class VmCompilerStatControllerTest {
+
+    private Timer timer;
+    private VmCompilerStatView view;
+    private VmRef ref;
+    private Runnable timerAction;
+    private ActionListener<Action> listener;
+
+    @Before
+    public void setup() {
+        ref = mock(VmRef.class);
+    }
+
+    @Test
+    public void testChartUpdate() {
+        final long SOME_TIMESTAMP = 12345;
+        final int SOME_VALUE = 1234;
+        final int LAST_TYPE = 2;
+
+        VmCompilerStat stat1 = new VmCompilerStat("foo-agent", "vmId", SOME_TIMESTAMP,
+                SOME_VALUE, SOME_VALUE, SOME_VALUE,
+                SOME_VALUE,
+                SOME_VALUE, LAST_TYPE, "Foo lastMethod",
+                LAST_TYPE, "Bar lastFailedMethod");
+
+        List<VmCompilerStat> stats = new ArrayList<VmCompilerStat>();
+        stats.add(stat1);
+
+        VmCompilerStatDao vmCompilerStatDAO = mock(VmCompilerStatDao.class);
+
+        when(vmCompilerStatDAO.getNewest(ref)).thenReturn(stat1);
+        when(vmCompilerStatDAO.getOldest(ref)).thenReturn(stat1);
+
+        setupWithVmCompilerStatDAO(vmCompilerStatDAO);
+
+        listener.actionPerformed(new ActionEvent<>(view, VmCompilerStatView.Action.VISIBLE));
+
+        verify(timer).start();
+        timerAction.run();
+        verify(view).setCurrentDisplay(isA(ViewData.class));
+
+        listener.actionPerformed(new ActionEvent<>(view, VmCompilerStatView.Action.HIDDEN));
+
+        verify(timer).stop();
+    }
+
+    @Test
+    public void verifyNoCompilerStatDataDoesNotNPE() {
+        setupWithVmCompilerStatDAO(mock(VmCompilerStatDao.class));
+        timerAction.run();
+    }
+
+    @SuppressWarnings("unchecked")
+    private void setupWithVmCompilerStatDAO(VmCompilerStatDao vmCompilerStatDao) {
+
+        timer = mock(Timer.class);
+        ArgumentCaptor<Runnable> timerActionCaptor = ArgumentCaptor.forClass(Runnable.class);
+        doNothing().when(timer).setAction(timerActionCaptor.capture());
+
+        TimerFactory timerFactory = mock(TimerFactory.class);
+        when(timerFactory.createTimer()).thenReturn(timer);
+        ApplicationService appSvc = mock(ApplicationService.class);
+        when(appSvc.getTimerFactory()).thenReturn(timerFactory);
+
+        view = mock(VmCompilerStatView.class);
+        @SuppressWarnings("rawtypes")
+        ArgumentCaptor<ActionListener> viewArgumentCaptor = ArgumentCaptor.forClass(ActionListener.class);
+        doNothing().when(view).addActionListener(viewArgumentCaptor.capture());
+
+        VmCompilerStatViewProvider viewProvider = mock(VmCompilerStatViewProvider.class);
+        when(viewProvider.createView()).thenReturn(view);
+
+        @SuppressWarnings("unused")
+        VmCompilerStatController controller = new VmCompilerStatController(appSvc, vmCompilerStatDao, ref, viewProvider);
+
+        listener = viewArgumentCaptor.getValue();
+        timerAction = timerActionCaptor.getValue();
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-core/src/test/java/com/redhat/thermostat/vm/compiler/client/locale/LocaleResourcesTest.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.client.locale;
+
+import com.redhat.thermostat.testutils.AbstractLocaleResourcesTest;
+import com.redhat.thermostat.vm.compiler.client.locale.LocaleResources;
+
+public class LocaleResourcesTest extends AbstractLocaleResourcesTest<LocaleResources> {
+
+    @Override
+    protected Class<LocaleResources> getEnumClass() {
+        return LocaleResources.class;
+    }
+
+    @Override
+    protected String getResourceBundle() {
+        return LocaleResources.RESOURCE_BUNDLE;
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-swing/pom.xml	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2012-2016 Red Hat, Inc.
+
+ This file is part of Thermostat.
+
+ Thermostat is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ Thermostat is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Thermostat; see the file COPYING.  If not see
+ <http://www.gnu.org/licenses/>.
+
+ Linking this code with other modules is making a combined work
+ based on this code.  Thus, the terms and conditions of the GNU
+ General Public License cover the whole combination.
+
+ As a special exception, the copyright holders of this code give
+ you permission to link this code with independent modules to
+ produce an executable, regardless of the license terms of these
+ independent modules, and to copy and distribute the resulting
+ executable under terms of your choice, provided that you also
+ meet, for each linked independent module, the terms and conditions
+ of the license of that module.  An independent module is a module
+ which is not derived from or based on this code.  If you modify
+ this code, you may extend this exception to your version of the
+ library, but you are not obligated to do so.  If you do not wish
+ to do so, delete this exception statement from your version.
+
+-->
+<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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>thermostat-vm-compiler</artifactId>
+    <groupId>com.redhat.thermostat</groupId>
+    <version>1.5.8-SNAPSHOT</version>
+  </parent>
+  <artifactId>thermostat-vm-compiler-client-swing</artifactId>
+  <packaging>bundle</packaging>
+  <name>Thermostat VM Compiler Swing Client plugin</name>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Private-Package>com.redhat.thermostat.vm.compiler.client.swing.internal</Private-Package>
+            <Bundle-Activator>com.redhat.thermostat.vm.compiler.client.swing.internal.Activator</Bundle-Activator>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-SymbolicName>com.redhat.thermostat.vm.compiler.client.swing</Bundle-SymbolicName>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easytesting</groupId>
+      <artifactId>fest-swing</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>net.java.openjdk.cacio</groupId>
+      <artifactId>cacio-tta</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jfree</groupId>
+      <artifactId>jfreechart</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-swing</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-compiler-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-test</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-swing/src/main/java/com/redhat/thermostat/vm/compiler/client/swing/internal/Activator.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.client.swing.internal;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+import com.redhat.thermostat.vm.compiler.client.core.VmCompilerStatViewProvider;
+
+public class Activator implements BundleActivator {
+
+    @Override
+    public void start(final BundleContext context) throws Exception {
+        VmCompilerStatViewProvider viewProvider = new SwingVmCompilerStatViewProvider();
+        // Unregistered on Activator.stop
+        context.registerService(VmCompilerStatViewProvider.class.getName(), viewProvider, null);
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-swing/src/main/java/com/redhat/thermostat/vm/compiler/client/swing/internal/SwingVmCompilerStatView.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.client.swing.internal;
+
+import java.awt.Component;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import javax.swing.JSplitPane;
+import javax.swing.SwingUtilities;
+import javax.swing.table.DefaultTableModel;
+
+import com.redhat.thermostat.client.swing.EdtHelper;
+import com.redhat.thermostat.client.swing.NonEditableTableModel;
+import com.redhat.thermostat.client.swing.SwingComponent;
+import com.redhat.thermostat.client.swing.components.HeaderPanel;
+import com.redhat.thermostat.client.swing.components.MultiChartPanel;
+import com.redhat.thermostat.client.swing.components.MultiChartPanel.DataGroup;
+import com.redhat.thermostat.client.swing.components.ThermostatScrollPane;
+import com.redhat.thermostat.client.swing.components.ThermostatTable;
+import com.redhat.thermostat.client.swing.experimental.ComponentVisibilityNotifier;
+import com.redhat.thermostat.common.Duration;
+import com.redhat.thermostat.common.model.Range;
+import com.redhat.thermostat.shared.locale.Translate;
+import com.redhat.thermostat.storage.model.DiscreteTimeData;
+import com.redhat.thermostat.vm.compiler.client.core.VmCompilerStatView;
+import com.redhat.thermostat.vm.compiler.client.locale.LocaleResources;
+
+public class SwingVmCompilerStatView extends VmCompilerStatView implements SwingComponent {
+
+    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
+
+    private final HeaderPanel visiblePanel;
+
+    private DefaultTableModel model;
+    private MultiChartPanel multiChart;
+
+    private DataGroup numberGroup;
+    private DataGroup timeGroup;
+
+    public SwingVmCompilerStatView() {
+        visiblePanel = new HeaderPanel();
+
+        visiblePanel.setHeader(t.localize(LocaleResources.VM_COMPILER_HEADER));
+
+        JSplitPane splitPane = new JSplitPane();
+        splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
+        splitPane.setOneTouchExpandable(true);
+
+        visiblePanel.setContent(splitPane);
+
+        model = createTableModel();
+
+        ThermostatTable table = new ThermostatTable(model);
+        ThermostatScrollPane tablePane = new ThermostatScrollPane(table);
+
+        splitPane.setTopComponent(tablePane);
+
+        multiChart = new MultiChartPanel();
+        numberGroup = multiChart.createGroup();
+        timeGroup = multiChart.createGroup();
+
+        splitPane.setBottomComponent(multiChart);
+        splitPane.setResizeWeight(0.5);
+
+        new ComponentVisibilityNotifier().initialize(visiblePanel, notifier);
+
+        addChartTypes();
+    }
+
+    private DefaultTableModel createTableModel() {
+        DefaultTableModel model = new NonEditableTableModel(11, 2);
+        Object[] columnIdentifiers = new Object[] {
+                t.localize(LocaleResources.STATS_TABLE_COLUMN_NAME).getContents(),
+                t.localize(LocaleResources.STATS_TABLE_COLUMN_VALUE).getContents()
+        };
+        Object[][] dataVector = new Object[][] {
+            new Object[] { t.localize(LocaleResources.STATS_TOTAL_COMPILES).getContents(), 0 },
+            new Object[] { t.localize(LocaleResources.STATS_TOTAL_BAILOUTS).getContents(), 0 },
+            new Object[] { t.localize(LocaleResources.STATS_TOTAL_INVALIDATES).getContents(), 0 },
+            new Object[] { t.localize(LocaleResources.STATS_COMPILATION_TIME).getContents(), 0 },
+            new Object[] { t.localize(LocaleResources.STATS_LAST_SIZE).getContents(), 0 },
+            new Object[] { t.localize(LocaleResources.STATS_LAST_TYPE).getContents(), 0 },
+            new Object[] { t.localize(LocaleResources.STATS_LAST_METHOD).getContents(), 0 },
+            new Object[] { t.localize(LocaleResources.STATS_LAST_FAILED_TYPE).getContents(), 0 },
+            new Object[] { t.localize(LocaleResources.STATS_LAST_FAILED_METHOD).getContents(), 0 },
+        };
+        model.setDataVector(dataVector, columnIdentifiers);
+        return model;
+    }
+
+    private void addChartTypes() {
+        for (Type type : Type.values()) {
+            DataGroup group = getGroup(type);
+            String tag = getTag(type);
+            multiChart.addChart(group, tag, type.getLabel());
+            multiChart.showChart(group, tag);
+        }
+
+        multiChart.getRangeAxis(numberGroup).setLabel(
+                t.localize(LocaleResources.STAT_CHART_NUMBER_AXIS).getContents());
+        multiChart.getRangeAxis(timeGroup).setLabel(
+                t.localize(LocaleResources.STAT_CHART_TIME_AXIS).getContents());
+    }
+
+    @Override
+    public void setCurrentDisplay(final ViewData data) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                final int VALUE_COLUMN = 1;
+
+                String[] values = {
+                        data.totalCompiles,
+                        data.totalBailouts,
+                        data.totalInvalidates,
+                        data.compilationTime,
+                        data.lastSize,
+                        data.lastType,
+                        data.lastMethod,
+                        data.lastFailedType,
+                        data.lastFailedMethod,
+                };
+
+                int row = 0;
+                for (String value : values) {
+                    model.setValueAt(value, row, VALUE_COLUMN);
+                    row++;
+                }
+            }
+
+        });
+    }
+
+    @Override
+    public Duration getUserDesiredDuration() {
+        try {
+            return new EdtHelper().callAndWait(new Callable<Duration>(){
+                public Duration call() {
+                    return multiChart.getUserDesiredDuration();
+                }
+            });
+        } catch (InvocationTargetException | InterruptedException e) {
+            return null;
+        }
+    }
+
+    @Override
+    public void setAvailableDataRange(Range<Long> availableDataRange) {
+        // TODO
+    }
+
+    @Override
+    public void addCompilerData(final Type type, final List<DiscreteTimeData<? extends Number>> data) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                String tag = getTag(type);
+                multiChart.addData(tag, data);
+            }
+        });
+    }
+
+    @Override
+    public void clearCompilerData(final Type type) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                String tag = getTag(type);
+                multiChart.clearData(tag);
+            }
+        });
+    }
+
+    private DataGroup getGroup(final Type type) {
+        final DataGroup group;
+        if (type == Type.TOTAL_BAILOUTS || type == Type.TOTAL_COMPILES || type == Type.TOTAL_INVALIDATES) {
+            group = numberGroup;
+        } else {
+            group = timeGroup;
+        }
+        return group;
+    }
+
+    private String getTag(final Type type) {
+        return type.name();
+    }
+
+    @Override
+    public Component getUiComponent() {
+        return visiblePanel;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-swing/src/main/java/com/redhat/thermostat/vm/compiler/client/swing/internal/SwingVmCompilerStatViewProvider.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.client.swing.internal;
+
+import com.redhat.thermostat.vm.compiler.client.core.VmCompilerStatView;
+import com.redhat.thermostat.vm.compiler.client.core.VmCompilerStatViewProvider;
+
+
+public class SwingVmCompilerStatViewProvider implements VmCompilerStatViewProvider {
+
+    @Override
+    public VmCompilerStatView createView() {
+        return new SwingVmCompilerStatView();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-swing/src/test/java/com/redhat/thermostat/vm/compiler/client/swing/internal/ActivatorTest.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.client.swing.internal;
+
+import static com.redhat.thermostat.testutils.Asserts.assertServiceIsRegistered;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.testutils.StubBundleContext;
+import com.redhat.thermostat.vm.compiler.client.core.VmCompilerStatViewProvider;
+
+public class ActivatorTest {
+
+    @Test
+    public void verifyStartRegistersViewProvider() throws Exception {
+        StubBundleContext ctx = new StubBundleContext();
+        Activator activator = new Activator();
+        activator.start(ctx);
+
+        assertServiceIsRegistered(ctx, VmCompilerStatViewProvider.class, SwingVmCompilerStatViewProvider.class);
+
+        assertEquals(1, ctx.getAllServices().size());
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/client-swing/src/test/java/com/redhat/thermostat/vm/compiler/client/swing/internal/SwingVmCompilerStatViewTest.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.client.swing.internal;
+
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+
+import com.redhat.thermostat.vm.compiler.client.core.VmCompilerStatView.ViewData;
+
+public class SwingVmCompilerStatViewTest {
+
+    public static void main(String[] args) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+
+                JFrame frame = new JFrame("Test");
+
+                SwingVmCompilerStatView compilerPanel = new SwingVmCompilerStatView();
+
+                int totalCompiles = 200;
+                int totalBailouts = 10;
+                int totalInvalidates = 5;
+
+                String compilationTime = "12.3 s";
+
+                String lastSize = "10 bytes";
+                String lastType = "OSR Compile";
+                String lastMethod = "org.foo.Bar.lastMethod()";
+
+                String lastFailedType = "Native Compile";
+                String lastFailedMethod = "org.Baz.lastFailedMethod()";
+
+                ViewData data = new ViewData();
+                data.totalCompiles = String.valueOf(totalCompiles);
+                data.totalBailouts = String.valueOf(totalBailouts);
+                data.totalInvalidates = String.valueOf(totalInvalidates);
+                data.compilationTime = compilationTime;
+                data.lastSize = lastSize;
+                data.lastType = lastType;
+                data.lastMethod = lastMethod;
+                data.lastFailedType = lastFailedType;
+                data.lastFailedType = lastFailedMethod;
+
+                compilerPanel.setCurrentDisplay(data);
+
+                frame.add(compilerPanel.getUiComponent());
+                frame.pack();
+                frame.setVisible(true);
+                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+            }
+        });
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/common/pom.xml	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2012-2016 Red Hat, Inc.
+
+ This file is part of Thermostat.
+
+ Thermostat is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ Thermostat is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Thermostat; see the file COPYING.  If not see
+ <http://www.gnu.org/licenses/>.
+
+ Linking this code with other modules is making a combined work
+ based on this code.  Thus, the terms and conditions of the GNU
+ General Public License cover the whole combination.
+
+ As a special exception, the copyright holders of this code give
+ you permission to link this code with independent modules to
+ produce an executable, regardless of the license terms of these
+ independent modules, and to copy and distribute the resulting
+ executable under terms of your choice, provided that you also
+ meet, for each linked independent module, the terms and conditions
+ of the license of that module.  An independent module is a module
+ which is not derived from or based on this code.  If you modify
+ this code, you may extend this exception to your version of the
+ library, but you are not obligated to do so.  If you do not wish
+ to do so, delete this exception statement from your version.
+
+-->
+<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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>thermostat-vm-compiler</artifactId>
+    <groupId>com.redhat.thermostat</groupId>
+    <version>1.5.8-SNAPSHOT</version>
+  </parent>
+  <artifactId>thermostat-vm-compiler-common</artifactId>
+  <packaging>bundle</packaging>
+  <name>Thermostat VM Compiler Common plugin</name>
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>true</filtering>
+        <excludes>
+          <exclude>**/*.png</exclude>
+        </excludes>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>false</filtering>
+        <includes>
+          <include>**/*.png</include>
+        </includes>
+      </resource>
+    </resources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-SymbolicName>com.redhat.thermostat.vm.compiler.common</Bundle-SymbolicName>
+            <Bundle-Activator>com.redhat.thermostat.vm.compiler.common.internal.Activator</Bundle-Activator>
+            <Export-Package>
+              com.redhat.thermostat.vm.compiler.common,
+              com.redhat.thermostat.vm.compiler.common.model
+            </Export-Package>
+            <Private-Package>
+              com.redhat.thermostat.vm.compiler.common.internal
+            </Private-Package>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-storage-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-test</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/common/src/main/java/com/redhat/thermostat/vm/compiler/common/ParsedVmCompilerStat.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.common;
+
+import java.util.concurrent.TimeUnit;
+
+import com.redhat.thermostat.common.Duration;
+import com.redhat.thermostat.common.Size;
+
+public class ParsedVmCompilerStat {
+
+    public static enum CompileType {
+        NO_COMPILE,
+        NORMAL_COMPILE,
+        OSR_COMPILE,
+        NATIVE_COMPILE,;
+    }
+
+    private final VmCompilerStat original;
+
+    public ParsedVmCompilerStat(VmCompilerStat stat) {
+        this.original = stat;
+    }
+
+    public long getTotalCompiles() {
+        return original.getTotalCompiles();
+    }
+
+    public long getTotalInvalidates() {
+        return original.getTotalInvalidates();
+    }
+
+    public long getTotalBailouts() {
+        return original.getTotalBailouts();
+    }
+
+    public Duration getCompilationTime() {
+        return new Duration(original.getCompilationTime(), TimeUnit.MILLISECONDS);
+    }
+
+    public CompileType getLastType() {
+        return getCompileType(original.getLastType());
+    }
+
+    public Size getLastSize() {
+        return Size.bytes(original.getLastSize());
+    }
+
+    public String getLastMethod() {
+        return toStandardMethodName(original.getLastMethod());
+    }
+
+    public CompileType getLastFailedType() {
+        return getCompileType(original.getLastFailedType());
+    }
+
+    public String getLastFailedMethod() {
+        return toStandardMethodName(original.getLastFailedMethod());
+    }
+
+    private CompileType getCompileType(long typeValue) {
+        if (typeValue < 0 || typeValue >= CompileType.values().length) {
+            throw new IllegalArgumentException("Unexpected compile-type code: " + typeValue);
+        }
+        return CompileType.values()[(int) typeValue];
+    }
+
+    private String toStandardMethodName(String encodedMethodName) {
+        if (encodedMethodName == null || encodedMethodName.trim().isEmpty()) {
+            return "<none>";
+        }
+        String[] parts = encodedMethodName.split(" ");
+        String className = parts[0].replace('/', '.');
+        String methodName = parts[1];
+        return className + "." + methodName + "(...)";
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/common/src/main/java/com/redhat/thermostat/vm/compiler/common/VmCompilerStat.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.common;
+
+import com.redhat.thermostat.storage.core.Entity;
+import com.redhat.thermostat.storage.core.Persist;
+import com.redhat.thermostat.storage.model.BasePojo;
+import com.redhat.thermostat.storage.model.TimeStampedPojo;
+
+@Entity
+public class VmCompilerStat extends BasePojo implements TimeStampedPojo {
+
+    // See the jdk sources for more information:
+    // - jdk/src/share/classes/sun/tools/jstat/resources/jstat_options
+    // - jdk/src/share/classes/sun/tools/jstat/resources/jstat_unsupported_options
+
+    public static final int UNKNOWN = -1;
+
+    private String vmId;
+    private long timestamp;
+
+    private long totalCompiles;
+    private long totalBailouts;
+    private long totalInvalidates;
+
+    /**
+     * There's unit no explicitly mentioned for this jstat value anywhere
+     * that I could find. The closest thing I got was the hotspot
+     * implementation referring to ComplilationMXBean which mentions the
+     * return value is in milliseconds.
+     */
+    private long compilationTime;
+
+    private long lastSize;
+
+    /**
+     * From hotspot code, this is an enum with the values:
+     * { no_compile, normal_compile, osr_compile, native_compile }
+     */
+    private long lastType;
+
+    /**
+     *  is of the form "name/of/package/Class$InnerClass methodName"
+     */
+    private String lastMethod;
+
+    /**
+     * From hotspot code, this is an enum with the values:
+     * { no_compile, normal_compile, osr_compile, native_compile }
+     */
+    private long lastFailedType;
+
+    /**
+     *  is of the form "name/of/package/Class$InnerClass methodName"
+     */
+    private String lastFailedMethod;
+
+    public VmCompilerStat() {
+        this(null, null, UNKNOWN,
+                UNKNOWN, UNKNOWN, UNKNOWN,
+                UNKNOWN,
+                UNKNOWN, UNKNOWN, null,
+                UNKNOWN, null);
+    }
+
+    public VmCompilerStat(String writerId, String vmId, long timestamp,
+            long totalCompiles, long totalBailouts, long totalInvalidates,
+            long compilationTime,
+            long lastSize, long lastType, String lastMethod,
+            long lastFailedType, String lastFailedMethod) {
+        super(writerId);
+        this.vmId = vmId;
+        this.timestamp = timestamp;
+        this.totalCompiles = totalCompiles;
+        this.totalBailouts = totalBailouts;
+        this.totalInvalidates = totalInvalidates;
+        this.compilationTime = compilationTime;
+        this.lastSize = lastSize;
+        this.lastType = lastType;
+        this.lastMethod = lastMethod;
+        this.lastFailedType = lastFailedType;
+        this.lastFailedMethod = lastFailedMethod;
+    }
+
+    @Persist
+    public String getVmId() {
+        return vmId;
+    }
+
+    @Persist
+    public void setVmId(String vmId) {
+        this.vmId = vmId;
+    }
+
+    @Persist
+    @Override
+    public long getTimeStamp() {
+        return timestamp;
+    }
+
+    @Persist
+    public void setTimeStamp(long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    /** Number of compilation tasks performed */
+    @Persist
+    public long getTotalCompiles() {
+        return totalCompiles;
+    }
+
+    @Persist
+    public void setTotalCompiles(long totalCompiles) {
+        this.totalCompiles = totalCompiles;
+    }
+
+    /** Number of failed compilation tasks */
+    @Persist
+    public long getTotalBailouts() {
+        return totalBailouts;
+    }
+
+    @Persist
+    public void setTotalBailouts(long totalBailouts) {
+        this.totalBailouts = totalBailouts;
+    }
+
+    /** Number of invalidated compilation tasks */
+    @Persist
+    public long getTotalInvalidates() {
+        return totalInvalidates;
+    }
+
+    @Persist
+    public void setTotalInvalidates(long totalInvalidates) {
+        this.totalInvalidates = totalInvalidates;
+    }
+
+    /** Time spent in compilation. Cumulative, measured in ms */
+    @Persist
+    public long getCompilationTime() {
+        return compilationTime;
+    }
+
+    /** Time spent in compilation. Cumulative, measured in ms */
+    @Persist
+    public void setCompilationTime(long compilationTime) {
+        this.compilationTime = compilationTime;
+    }
+
+    /** Code Size in bytes of last compilation */
+    @Persist
+    public long getLastSize() {
+        return lastSize;
+    }
+
+    @Persist
+    public void setLastSize(long lastSize) {
+        this.lastSize = lastSize;
+    }
+
+    /** Type of last compilation */
+    @Persist
+    public long getLastType() {
+        return lastType;
+    }
+
+    @Persist
+    public void setLastType(long lastType) {
+        this.lastType = lastType;
+    }
+
+    /** Name of class and method for last compile */
+    @Persist
+    public String getLastMethod() {
+        return lastMethod;
+    }
+
+    @Persist
+    public void setLastMethod(String lastMethod) {
+        this.lastMethod = lastMethod;
+    }
+
+    /** Type of last failed compilation */
+    @Persist
+    public long getLastFailedType() {
+        return lastFailedType;
+    }
+
+    @Persist
+    public void setLastFailedType(long lastFailedType) {
+        this.lastFailedType = lastFailedType;
+    }
+
+    /** Name of class and method for last failed compile */
+    @Persist
+    public String getLastFailedMethod() {
+        return lastFailedMethod;
+    }
+
+    @Persist
+    public void setLastFailedMethod(String lastFailedMethod) {
+        this.lastFailedMethod = lastFailedMethod;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/common/src/main/java/com/redhat/thermostat/vm/compiler/common/VmCompilerStatDao.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.common;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.redhat.thermostat.annotations.Service;
+import com.redhat.thermostat.storage.core.Category;
+import com.redhat.thermostat.storage.core.Key;
+import com.redhat.thermostat.storage.core.VmRef;
+
+@Service
+public interface VmCompilerStatDao {
+
+    static final Key<Long> totalCompilesKey = new Key<>("totalCompiles");
+    static final Key<Long> totalBailoutsKey = new Key<>("totalBailouts");
+    static final Key<Long> totalInvalidatesKey = new Key<>("totalInvalidates");
+    static final Key<Long> compilationTimeKey = new Key<>("compilationTime");
+    static final Key<Long> lastSizeKey = new Key<>("lastSize");
+    static final Key<Long> lastTypeKey = new Key<>("lastType");
+    static final Key<String> lastMethodKey = new Key<>("lastMethod");
+    static final Key<Long> lastFailedTypeKey = new Key<>("lastFailedType");
+    static final Key<String> lastFailedMethodKey = new Key<>("lastFailedMethod");
+
+
+    static final Category<VmCompilerStat> vmCompilerStatsCategory = new Category<>(
+            "vm-compiler-stats", VmCompilerStat.class,
+            Arrays.<Key<?>>asList(
+                    Key.AGENT_ID, Key.VM_ID, Key.TIMESTAMP,
+                    totalCompilesKey, totalBailoutsKey, totalInvalidatesKey,
+                    compilationTimeKey,
+                    lastSizeKey, lastTypeKey, lastMethodKey,
+                    lastFailedTypeKey, lastFailedMethodKey),
+            Arrays.<Key<?>>asList(Key.TIMESTAMP));
+
+    public List<VmCompilerStat> getLatestCompilerStats(VmRef ref, long since);
+
+    public List<VmCompilerStat> getCompilerStats(VmRef ref, long since, long to);
+
+    public void putVmCompilerStat(VmCompilerStat stat);
+
+    public abstract VmCompilerStat getOldest(VmRef ref);
+
+    public abstract VmCompilerStat getNewest(VmRef ref);
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/common/src/main/java/com/redhat/thermostat/vm/compiler/common/internal/Activator.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.common.internal;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+
+import com.redhat.thermostat.storage.core.Storage;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+
+public class Activator implements BundleActivator {
+
+    private ServiceTracker tracker;
+    private ServiceRegistration reg;
+
+    @Override
+    public void start(BundleContext context) throws Exception {
+        tracker = new ServiceTracker(context, Storage.class.getName(), null) {
+            @Override
+            public Object addingService(ServiceReference reference) {
+                Storage storage = (Storage) context.getService(reference);
+                VmCompilerStatDao vmCompilerStatDao = new VmCompilerStatDaoImpl(storage);
+                reg = context.registerService(VmCompilerStatDao.class.getName(), vmCompilerStatDao, null);
+                return super.addingService(reference);
+            }
+
+            @Override
+            public void removedService(ServiceReference reference,
+                    Object service) {
+                reg.unregister();
+                super.removedService(reference, service);
+            }
+        };
+        tracker.open();
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        tracker.close();
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/common/src/main/java/com/redhat/thermostat/vm/compiler/common/internal/VmCompilerStatCategoryRegistration.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.common.internal;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import com.redhat.thermostat.storage.core.auth.CategoryRegistration;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+
+/**
+ * Registers the category used by this maven module. The web storage
+ * endpoint only allows categories to be registered which it knows of
+ * ahead of time.
+ *
+ */
+public class VmCompilerStatCategoryRegistration implements CategoryRegistration {
+
+    @Override
+    public Set<String> getCategoryNames() {
+        Set<String> categories = new HashSet<>(1);
+        categories.add(VmCompilerStatDao.vmCompilerStatsCategory.getName());
+        return categories;
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/common/src/main/java/com/redhat/thermostat/vm/compiler/common/internal/VmCompilerStatDaoImpl.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.common.internal;
+
+import java.util.List;
+import java.util.logging.Logger;
+
+import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.storage.core.Key;
+import com.redhat.thermostat.storage.core.PreparedStatement;
+import com.redhat.thermostat.storage.core.Storage;
+import com.redhat.thermostat.storage.core.VmBoundaryPojoGetter;
+import com.redhat.thermostat.storage.core.VmLatestPojoListGetter;
+import com.redhat.thermostat.storage.core.VmRef;
+import com.redhat.thermostat.storage.core.VmTimeIntervalPojoListGetter;
+import com.redhat.thermostat.storage.dao.AbstractDao;
+import com.redhat.thermostat.storage.dao.AbstractDaoStatement;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStat;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+
+class VmCompilerStatDaoImpl extends AbstractDao implements VmCompilerStatDao {
+
+    private static final Logger logger = LoggingUtils.getLogger(VmCompilerStatDaoImpl.class);
+
+    static final String DESC_ADD_VM_COMPILER_STAT = "ADD " + vmCompilerStatsCategory.getName() +
+            " SET '" + Key.AGENT_ID.getName() + "' = ?s , " +
+                 "'" + Key.VM_ID.getName() + "' = ?s , " +
+                 "'" + Key.TIMESTAMP.getName() + "' = ?l , " +
+                 "'" + totalCompilesKey.getName() + "' = ?l , " +
+                 "'" + totalBailoutsKey.getName() + "' = ?l , " +
+                 "'" + totalInvalidatesKey.getName() + "' = ?l , " +
+                 "'" + compilationTimeKey.getName() + "' = ?l , " +
+                 "'" + lastSizeKey.getName() + "' = ?l , " +
+                 "'" + lastTypeKey.getName() + "' = ?l , " +
+                 "'" + lastMethodKey.getName() + "' = ?s , " +
+                 "'" + lastFailedTypeKey.getName() + "' = ?l , " +
+                 "'" + lastFailedMethodKey.getName() + "' = ?s";
+
+    private final Storage storage;
+    private final VmLatestPojoListGetter<VmCompilerStat> latestGetter;
+    private final VmTimeIntervalPojoListGetter<VmCompilerStat> intervalGetter;
+    private final VmBoundaryPojoGetter<VmCompilerStat> boundaryGetter;
+
+    VmCompilerStatDaoImpl(Storage storage) {
+        this.storage = storage;
+        storage.registerCategory(vmCompilerStatsCategory);
+        this.latestGetter = new VmLatestPojoListGetter<>(storage, vmCompilerStatsCategory);
+        this.intervalGetter = new VmTimeIntervalPojoListGetter<>(storage, vmCompilerStatsCategory);
+        this.boundaryGetter = new VmBoundaryPojoGetter<>(storage, vmCompilerStatsCategory);
+    }
+
+    @Override
+    public List<VmCompilerStat> getLatestCompilerStats(VmRef ref, long lastUpdateTime) {
+        return latestGetter.getLatest(ref, lastUpdateTime);
+    }
+
+    @Override
+    public List<VmCompilerStat> getCompilerStats(VmRef ref, long since, long to) {
+        return intervalGetter.getLatest(ref, since, to);
+    }
+
+    @Override
+    public void putVmCompilerStat(final VmCompilerStat stat) {
+        executeStatement(new AbstractDaoStatement<VmCompilerStat>(storage, vmCompilerStatsCategory, DESC_ADD_VM_COMPILER_STAT) {
+            @Override
+            public PreparedStatement<VmCompilerStat> customize(PreparedStatement<VmCompilerStat> preparedStatement) {
+                preparedStatement.setString(0, stat.getAgentId());
+                preparedStatement.setString(1, stat.getVmId());
+                preparedStatement.setLong(2, stat.getTimeStamp());
+                preparedStatement.setLong(3, stat.getTotalCompiles());
+                preparedStatement.setLong(4, stat.getTotalBailouts());
+                preparedStatement.setLong(5, stat.getTotalInvalidates());
+                preparedStatement.setLong(6, stat.getCompilationTime());
+                preparedStatement.setLong(7, stat.getLastSize());
+                preparedStatement.setLong(8, stat.getLastType());
+                preparedStatement.setString(9, stat.getLastMethod());
+                preparedStatement.setLong(10, stat.getLastFailedType());
+                preparedStatement.setString(11, stat.getLastFailedMethod());
+                return preparedStatement;
+            }
+        });
+    }
+
+    @Override
+    public VmCompilerStat getOldest(final VmRef ref) {
+        return boundaryGetter.getOldestStat(ref);
+    }
+
+    @Override
+    public VmCompilerStat getNewest(final VmRef ref) {
+        return boundaryGetter.getNewestStat(ref);
+    }
+
+    @Override
+    protected Logger getLogger() {
+        return logger;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/common/src/main/java/com/redhat/thermostat/vm/compiler/common/internal/VmCompilerStatDaoImplStatementDescriptorRegistration.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.common.internal;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import com.redhat.thermostat.storage.core.VmBoundaryPojoGetter;
+import com.redhat.thermostat.storage.core.VmLatestPojoListGetter;
+import com.redhat.thermostat.storage.core.VmTimeIntervalPojoListGetter;
+import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+
+/**
+ * Registers the prepared query issued by this maven module via
+ * {@link VmLatestPojoListGetter}.
+ *
+ */
+public class VmCompilerStatDaoImplStatementDescriptorRegistration implements
+        StatementDescriptorRegistration {
+
+    static final String LATEST = String.format(VmLatestPojoListGetter.VM_LATEST_QUERY_FORMAT,
+            VmCompilerStatDao.vmCompilerStatsCategory.getName());
+    static final String RANGE = String.format(VmTimeIntervalPojoListGetter.VM_INTERVAL_QUERY_FORMAT,
+            VmCompilerStatDao.vmCompilerStatsCategory.getName());
+    static final String LATEST_STAT = String.format(VmBoundaryPojoGetter.DESC_NEWEST_VM_STAT,
+            VmCompilerStatDao.vmCompilerStatsCategory.getName());
+    static final String OLDEST_STAT = String.format(VmBoundaryPojoGetter.DESC_OLDEST_VM_STAT,
+            VmCompilerStatDao.vmCompilerStatsCategory.getName());
+
+    @Override
+    public Set<String> getStatementDescriptors() {
+        Set<String> descs = new HashSet<>(1);
+        descs.add(LATEST);
+        descs.add(RANGE);
+        descs.add(LATEST_STAT);
+        descs.add(OLDEST_STAT);
+        descs.add(VmCompilerStatDaoImpl.DESC_ADD_VM_COMPILER_STAT);
+        return descs;
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.CategoryRegistration	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,2 @@
+com.redhat.thermostat.vm.compiler.common.internal.VmCompilerStatCategoryRegistration
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,2 @@
+com.redhat.thermostat.vm.compiler.common.internal.VmCompilerStatDaoImplStatementDescriptorRegistration
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/common/src/test/java/com/redhat/thermostat/vm/compiler/common/VmCompilerStatTest.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.common;
+
+import com.redhat.thermostat.testutils.DataObjectTest;
+
+public class VmCompilerStatTest extends DataObjectTest {
+
+    @Override
+    public Class<?>[] getDataClasses() {
+        return new Class[] { VmCompilerStat.class };
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/common/src/test/java/com/redhat/thermostat/vm/compiler/common/internal/ActivatorTest.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.common.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.storage.core.Storage;
+import com.redhat.thermostat.testutils.StubBundleContext;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+import com.redhat.thermostat.vm.compiler.common.internal.Activator;
+import com.redhat.thermostat.vm.compiler.common.internal.VmCompilerStatDaoImpl;
+
+public class ActivatorTest {
+
+    @Test
+    public void verifyActivatorDoesNotRegisterServiceOnMissingDeps() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        assertEquals(0, context.getAllServices().size());
+        assertEquals(1, context.getServiceListeners().size());
+
+        activator.stop(context);
+    }
+
+    @Test
+    public void verifyActivatorRegistersServices() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+        Storage storage = mock(Storage.class);
+
+        context.registerService(Storage.class, storage, null);
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        assertTrue(context.isServiceRegistered(VmCompilerStatDao.class.getName(), VmCompilerStatDaoImpl.class));
+
+        activator.stop(context);
+
+        assertEquals(0, context.getServiceListeners().size());
+        assertEquals(1, context.getAllServices().size());
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/common/src/test/java/com/redhat/thermostat/vm/compiler/common/internal/VmCompilerStatCategoryRegistrationTest.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.common.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Set;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.storage.core.auth.CategoryRegistration;
+import com.redhat.thermostat.testutils.ServiceLoaderTest;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+
+public class VmCompilerStatCategoryRegistrationTest extends ServiceLoaderTest<CategoryRegistration> {
+
+    public VmCompilerStatCategoryRegistrationTest() {
+        super(CategoryRegistration.class, STORAGE_SERVICES, VmCompilerStatCategoryRegistration.class);
+    }
+
+    @Test
+    public void registersAllCategories() {
+        VmCompilerStatCategoryRegistration reg = new VmCompilerStatCategoryRegistration();
+        Set<String> categories = reg.getCategoryNames();
+        assertEquals(1, categories.size());
+        assertFalse("null descriptor not allowed", categories.contains(null));
+        assertTrue(categories.contains(VmCompilerStatDao.vmCompilerStatsCategory.getName()));
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/common/src/test/java/com/redhat/thermostat/vm/compiler/common/internal/VmCompilerStatDaoImplStatementDescriptorRegistrationTest.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.common.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import java.util.Set;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration;
+import com.redhat.thermostat.testutils.ServiceLoaderTest;
+
+public class VmCompilerStatDaoImplStatementDescriptorRegistrationTest extends ServiceLoaderTest<StatementDescriptorRegistration> {
+
+    public VmCompilerStatDaoImplStatementDescriptorRegistrationTest() {
+        super(StatementDescriptorRegistration.class, STORAGE_SERVICES, VmCompilerStatDaoImplStatementDescriptorRegistration.class);
+    }
+
+    @Test
+    public void registersAllDescriptors() {
+        VmCompilerStatDaoImplStatementDescriptorRegistration reg = new VmCompilerStatDaoImplStatementDescriptorRegistration();
+        Set<String> descriptors = reg.getStatementDescriptors();
+        assertEquals(5, descriptors.size());
+        assertFalse("null descriptor not allowed", descriptors.contains(null));
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/common/src/test/java/com/redhat/thermostat/vm/compiler/common/internal/VmCompilerStatDaoImplTest.java	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.compiler.common.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import com.redhat.thermostat.storage.core.Cursor;
+import com.redhat.thermostat.storage.core.DescriptorParsingException;
+import com.redhat.thermostat.storage.core.HostRef;
+import com.redhat.thermostat.storage.core.Key;
+import com.redhat.thermostat.storage.core.PreparedStatement;
+import com.redhat.thermostat.storage.core.StatementDescriptor;
+import com.redhat.thermostat.storage.core.StatementExecutionException;
+import com.redhat.thermostat.storage.core.Storage;
+import com.redhat.thermostat.storage.core.VmRef;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStat;
+import com.redhat.thermostat.vm.compiler.common.VmCompilerStatDao;
+import com.redhat.thermostat.vm.compiler.common.internal.VmCompilerStatDaoImpl;
+
+public class VmCompilerStatDaoImplTest {
+
+    private static final Long TIMESTAMP = 1234L;
+    private static final String VM_ID = "vmId";
+    private static final Long TOTAL_COMPILES = 12345L;
+    private static final Long TOTAL_BAILOUTS= 2345L;
+    private static final Long TOTAL_INVALIDATES = 3456L;
+    private static final Long COMPILATION_TIME = 4567L;
+    private static final Long LAST_SIZE = 5678L;
+    private static final Long LAST_TYPE = 6789L;
+    private static final String LAST_METHOD = "lastMethod()";
+    private static final Long LAST_FAILED_TYPE = 789L;
+    private static final String LAST_FAILED_METHOD = "lastFailedMethod()";
+
+    @Test
+    public void testStatementDescriptorsAreSane() {
+        String addVmCompilerStat = "ADD vm-compiler-stats SET 'agentId' = ?s , " +
+                                                "'vmId' = ?s , " +
+                                                "'timeStamp' = ?l , " +
+                                                "'totalCompiles' = ?l , " +
+                                                "'totalBailouts' = ?l , " +
+                                                "'totalInvalidates' = ?l , " +
+                                                "'compilationTime' = ?l , " +
+                                                "'lastSize' = ?l , " +
+                                                "'lastType' = ?l , " +
+                                                "'lastMethod' = ?s , " +
+                                                "'lastFailedType' = ?l , " +
+                                                "'lastFailedMethod' = ?s";
+
+        assertEquals(addVmCompilerStat, VmCompilerStatDaoImpl.DESC_ADD_VM_COMPILER_STAT);
+    }
+
+    @Test
+    public void testCategory() {
+        assertEquals("vm-compiler-stats", VmCompilerStatDao.vmCompilerStatsCategory.getName());
+        Collection<Key<?>> keys = VmCompilerStatDao.vmCompilerStatsCategory.getKeys();
+        assertTrue(keys.contains(new Key<>("agentId")));
+        assertTrue(keys.contains(new Key<Integer>("vmId")));
+        assertTrue(keys.contains(new Key<Long>("timeStamp")));
+        assertTrue(keys.contains(new Key<Long>("totalCompiles")));
+        assertTrue(keys.contains(new Key<Long>("totalBailouts")));
+        assertTrue(keys.contains(new Key<Long>("totalInvalidates")));
+        assertTrue(keys.contains(new Key<Long>("compilationTime")));
+        assertTrue(keys.contains(new Key<Long>("lastSize")));
+        assertTrue(keys.contains(new Key<Long>("lastType")));
+        assertTrue(keys.contains(new Key<Long>("lastMethod")));
+        assertTrue(keys.contains(new Key<Long>("lastFailedType")));
+        assertTrue(keys.contains(new Key<Long>("lastFailedMethod")));
+        assertEquals(12, keys.size());
+    }
+
+    @Test
+    public void testGetLatestCompilerStatsBasic() throws DescriptorParsingException, StatementExecutionException {
+
+        VmCompilerStat vmCompilerStat = getCompilerStat();
+
+        @SuppressWarnings("unchecked")
+        Cursor<VmCompilerStat> cursor = mock(Cursor.class);
+        when(cursor.hasNext()).thenReturn(true).thenReturn(false);
+        when(cursor.next()).thenReturn(vmCompilerStat);
+
+        Storage storage = mock(Storage.class);
+        @SuppressWarnings("unchecked")
+        PreparedStatement<VmCompilerStat> stmt = (PreparedStatement<VmCompilerStat>) mock(PreparedStatement.class);
+        when(storage.prepareStatement(anyDescriptor())).thenReturn(stmt);
+        when(stmt.executeQuery()).thenReturn(cursor);
+
+        HostRef hostRef = mock(HostRef.class);
+        when(hostRef.getAgentId()).thenReturn("system");
+
+        VmRef vmRef = mock(VmRef.class);
+        when(vmRef.getHostRef()).thenReturn(hostRef);
+        when(vmRef.getVmId()).thenReturn(VM_ID);
+
+        VmCompilerStatDao dao = new VmCompilerStatDaoImpl(storage);
+        List<VmCompilerStat> vmCompilerStats = dao.getLatestCompilerStats(vmRef, Long.MIN_VALUE);
+
+        verify(storage).prepareStatement(anyDescriptor());
+        verify(stmt).setString(0, "system");
+        verify(stmt).setString(1, VM_ID);
+        verify(stmt).setLong(2, Long.MIN_VALUE);
+        verify(stmt).executeQuery();
+        verifyNoMoreInteractions(stmt);
+
+        assertEquals(1, vmCompilerStats.size());
+        VmCompilerStat stat = vmCompilerStats.get(0);
+        assertEquals(VM_ID, stat.getVmId());
+        assertEquals(TIMESTAMP, (Long) stat.getTimeStamp());
+        assertEquals(TOTAL_COMPILES, (Long) stat.getTotalCompiles());
+        assertEquals(TOTAL_BAILOUTS, (Long) stat.getTotalBailouts());
+        assertEquals(TOTAL_INVALIDATES, (Long) stat.getTotalInvalidates());
+        assertEquals(COMPILATION_TIME, (Long) stat.getCompilationTime());
+        assertEquals(LAST_SIZE, (Long) stat.getLastSize());
+        assertEquals(LAST_TYPE, (Long) stat.getLastType());
+        assertEquals(LAST_METHOD, stat.getLastMethod());
+        assertEquals(LAST_FAILED_TYPE, (Long) stat.getLastFailedType());
+        assertEquals(LAST_FAILED_METHOD, stat.getLastFailedMethod());
+    }
+
+    @SuppressWarnings("unchecked")
+    private StatementDescriptor<VmCompilerStat> anyDescriptor() {
+        return (StatementDescriptor<VmCompilerStat>) any(StatementDescriptor.class);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testPutVmCompilerStat() throws DescriptorParsingException, StatementExecutionException {
+
+        Storage storage = mock(Storage.class);
+        PreparedStatement<VmCompilerStat> add = mock(PreparedStatement.class);
+        when(storage.prepareStatement(any(StatementDescriptor.class))).thenReturn(add);
+
+        VmCompilerStat stat = getCompilerStat();
+        VmCompilerStatDao dao = new VmCompilerStatDaoImpl(storage);
+        dao.putVmCompilerStat(stat);
+
+        @SuppressWarnings("rawtypes")
+        ArgumentCaptor<StatementDescriptor> captor = ArgumentCaptor.forClass(StatementDescriptor.class);
+
+        verify(storage).prepareStatement(captor.capture());
+        StatementDescriptor<?> desc = captor.getValue();
+        assertEquals(VmCompilerStatDaoImpl.DESC_ADD_VM_COMPILER_STAT, desc.getDescriptor());
+
+        verify(add).setString(0, stat.getAgentId());
+        verify(add).setString(1, stat.getVmId());
+        verify(add).setLong(2, stat.getTimeStamp());
+        verify(add).setLong(3, stat.getTotalCompiles());
+        verify(add).setLong(4, stat.getTotalBailouts());
+        verify(add).setLong(5, stat.getTotalInvalidates());
+        verify(add).setLong(6, stat.getCompilationTime());
+        verify(add).setLong(7, stat.getLastSize());
+        verify(add).setLong(8, stat.getLastType());
+        verify(add).setString(9, stat.getLastMethod());
+        verify(add).setLong(10, stat.getLastFailedType());
+        verify(add).setString(11, stat.getLastFailedMethod());
+        verify(add).execute();
+        verifyNoMoreInteractions(add);
+    }
+
+    private VmCompilerStat getCompilerStat() {
+        return new VmCompilerStat("foo-agent", VM_ID, TIMESTAMP,
+                TOTAL_COMPILES, TOTAL_BAILOUTS, TOTAL_INVALIDATES,
+                COMPILATION_TIME,
+                LAST_SIZE, LAST_TYPE, LAST_METHOD,
+                LAST_FAILED_TYPE, LAST_FAILED_METHOD);
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/distribution/pom.xml	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2012-2016 Red Hat, Inc.
+
+ This file is part of Thermostat.
+
+ Thermostat is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ Thermostat is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Thermostat; see the file COPYING.  If not see
+ <http://www.gnu.org/licenses/>.
+
+ Linking this code with other modules is making a combined work
+ based on this code.  Thus, the terms and conditions of the GNU
+ General Public License cover the whole combination.
+
+ As a special exception, the copyright holders of this code give
+ you permission to link this code with independent modules to
+ produce an executable, regardless of the license terms of these
+ independent modules, and to copy and distribute the resulting
+ executable under terms of your choice, provided that you also
+ meet, for each linked independent module, the terms and conditions
+ of the license of that module.  An independent module is a module
+ which is not derived from or based on this code.  If you modify
+ this code, you may extend this exception to your version of the
+ library, but you are not obligated to do so.  If you do not wish
+ to do so, delete this exception statement from your version.
+
+-->
+<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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.redhat.thermostat</groupId>
+    <artifactId>thermostat-vm-compiler</artifactId>
+    <version>1.5.8-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-vm-compiler-distribution</artifactId>
+  <packaging>pom</packaging>
+
+  <name>Thermostat VM Compiler plugin distribution</name>
+
+  <properties>
+    <thermostat.plugin>vm-compiler</thermostat.plugin>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <dependencies>
+          <dependency>
+            <groupId>com.redhat.thermostat</groupId>
+            <artifactId>thermostat-assembly</artifactId>
+            <version>${project.version}</version>
+          </dependency>
+        </dependencies>
+        <configuration>
+          <descriptorRefs>
+            <descriptorRef>plugin-assembly</descriptorRef>
+          </descriptorRefs>
+          <appendAssemblyId>false</appendAssemblyId>
+        </configuration>
+        <executions>
+          <execution>
+            <id>assemble-plugin</id>
+            <phase>package</phase>
+            <goals>
+              <goal>single</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <!-- Explicitly list all plug-in artifacts, transitive dependencies
+       are not included in assembly. -->
+  <dependencies>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-compiler-common</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-compiler-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-compiler-client-swing</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-compiler-agent</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+
+</project>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/distribution/thermostat-plugin.xml	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<!--
+
+ Copyright 2012-2016 Red Hat, Inc.
+
+ This file is part of Thermostat.
+
+ Thermostat is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ Thermostat is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Thermostat; see the file COPYING.  If not see
+ <http://www.gnu.org/licenses/>.
+
+ Linking this code with other modules is making a combined work
+ based on this code.  Thus, the terms and conditions of the GNU
+ General Public License cover the whole combination.
+
+ As a special exception, the copyright holders of this code give
+ you permission to link this code with independent modules to
+ produce an executable, regardless of the license terms of these
+ independent modules, and to copy and distribute the resulting
+ executable under terms of your choice, provided that you also
+ meet, for each linked independent module, the terms and conditions
+ of the license of that module.  An independent module is a module
+ which is not derived from or based on this code.  If you modify
+ this code, you may extend this exception to your version of the
+ library, but you are not obligated to do so.  If you do not wish
+ to do so, delete this exception statement from your version.
+
+-->
+<plugin xmlns="http://icedtea.classpath.org/thermostat/plugins/v1.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://icedtea.classpath.org/thermostat/plugins/v1.0 thermostat-plugin.xsd">
+  <extensions>
+    <extension>
+      <name>gui</name>
+      <bundles>
+        <bundle><symbolic-name>com.redhat.thermostat.vm.compiler.common</symbolic-name><version>${project.version}</version></bundle>
+        <bundle><symbolic-name>com.redhat.thermostat.vm.compiler.client.core</symbolic-name><version>${project.version}</version></bundle>
+        <bundle><symbolic-name>com.redhat.thermostat.vm.compiler.client.swing</symbolic-name><version>${project.version}</version></bundle>
+      </bundles>
+    </extension>
+    <extension>
+      <name>agent</name>
+      <bundles>
+        <bundle><symbolic-name>com.redhat.thermostat.vm.compiler.common</symbolic-name><version>${project.version}</version></bundle>
+        <bundle><symbolic-name>com.redhat.thermostat.vm.compiler.agent</symbolic-name><version>${project.version}</version></bundle>
+      </bundles>
+    </extension>
+  </extensions>
+</plugin>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-compiler/pom.xml	Wed Jun 22 09:04:21 2016 -0400
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2012-2016 Red Hat, Inc.
+
+ This file is part of Thermostat.
+
+ Thermostat is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ Thermostat is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Thermostat; see the file COPYING.  If not see
+ <http://www.gnu.org/licenses/>.
+
+ Linking this code with other modules is making a combined work
+ based on this code.  Thus, the terms and conditions of the GNU
+ General Public License cover the whole combination.
+
+ As a special exception, the copyright holders of this code give
+ you permission to link this code with independent modules to
+ produce an executable, regardless of the license terms of these
+ independent modules, and to copy and distribute the resulting
+ executable under terms of your choice, provided that you also
+ meet, for each linked independent module, the terms and conditions
+ of the license of that module.  An independent module is a module
+ which is not derived from or based on this code.  If you modify
+ this code, you may extend this exception to your version of the
+ library, but you are not obligated to do so.  If you do not wish
+ to do so, delete this exception statement from your version.
+
+-->
+<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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.redhat.thermostat</groupId>
+    <artifactId>thermostat</artifactId>
+    <version>1.5.8-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-vm-compiler</artifactId>
+  <packaging>pom</packaging>
+
+  <name>Thermostat VM Compiler plugin</name>
+
+  <modules>
+    <module>agent</module>
+    <module>client-core</module>
+    <module>client-swing</module>
+    <module>common</module>
+    <module>distribution</module>
+  </modules>
+
+</project>
+
--- a/web/war/pom.xml	Tue Jun 21 09:25:52 2016 -0400
+++ b/web/war/pom.xml	Wed Jun 22 09:04:21 2016 -0400
@@ -186,6 +186,11 @@
       <artifactId>thermostat-vm-io-common</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-compiler-common</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
 
   <build>