changeset 2760:22f2b3ea3609

Add byteman integration services Reviewed-by: jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-September/025152.html
author Jie Kang <jkang@redhat.com>
date Fri, 22 Sep 2017 10:10:52 -0400
parents e67aeba2003a
children 87f42669d0f4
files distribution/assembly/plugin-assembly.xml distribution/pom.xml plugins/pom.xml plugins/vm-byteman/agent/pom.xml plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/BytemanMetric.java plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/VmBytemanDAO.java plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/VmBytemanStatus.java plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManager.java plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiver.java plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequest.java plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiver.java plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanDAOImpl.java plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanMetricsStore.java plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanStatusStore.java plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapters/BytemanMetricTypeAdapter.java plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapters/BytemanTypeAdapterFactory.java plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapters/GsonCreator.java plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapters/VmBytemanStatusTypeAdapter.java plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManagerTest.java plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiverTest.java plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiverTest.java plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/IPCEndpointsManagerTest.java plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapter/BytemanMetricTypeAdapterTest.java plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapter/JsonHelper.java plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapter/VmBytemanStatusTypeAdapterTest.java plugins/vm-byteman/common/pom.xml plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/BytemanMetric.java plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/BytemanMetricDataExtractor.java plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/BytemanMetricTypeAdapterFactory.java plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/VmBytemanDAO.java plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/VmBytemanStatus.java plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/command/BytemanRequest.java plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/command/BytemanRequestResponseListener.java plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricTypeAdapter.java plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricWebTypeAdapter.java plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/LocaleResources.java plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanDAOImpl.java plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanMetricDAOCategoryRegistration.java plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanMetricDAOImplStatementDescriptorRegistration.java plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanStatusTypeAdapter.java plugins/vm-byteman/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.CategoryRegistration plugins/vm-byteman/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration plugins/vm-byteman/common/src/main/resources/com/redhat/thermostat/vm/byteman/common/internal/strings.properties plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/BytemanMetricDataExtractorTest.java plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/JsonHelper.java plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/command/BytemanRequestResponseListenerTest.java plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/command/BytemanRequestTest.java plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricTypeAdapterTest.java plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricWebTypeAdapterTest.java plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/LocaleResourcesTest.java plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanStatusTypeAdapterTest.java plugins/vm-byteman/distribution/assemblies/plugin-assembly.xml plugins/vm-byteman/distribution/configFiles/gateway.properties plugins/vm-byteman/distribution/thermostat-plugin.xml plugins/vm-byteman/pom.xml
diffstat 55 files changed, 1560 insertions(+), 2338 deletions(-) [+]
line wrap: on
line diff
--- a/distribution/assembly/plugin-assembly.xml	Mon Sep 18 14:04:16 2017 +0200
+++ b/distribution/assembly/plugin-assembly.xml	Fri Sep 22 10:10:52 2017 -0400
@@ -57,16 +57,16 @@
         <include>com.redhat.thermostat:thermostat-vm-gc-distribution</include>
         <include>com.redhat.thermostat:thermostat-vm-memory-distribution</include>
         <include>com.redhat.thermostat:thermostat-vm-io-distribution</include>
+        <include>com.redhat.thermostat:thermostat-vm-byteman-distribution</include>
+        <include>com.redhat.thermostat:thermostat-commands-distribution</include>
+        <include>com.redhat.thermostat:thermostat-killvm-distribution</include>
 <!--        <include>com.redhat.thermostat:thermostat-numa-distribution</include>-->
 <!--        <include>com.redhat.thermostat:thermostat-thread-distribution</include>-->
-<!--        <include>com.redhat.thermostat:thermostat-vm-byteman-distribution</include>-->
 <!--        <include>com.redhat.thermostat:thermostat-vm-classstat-distribution</include>-->
 <!--        <include>com.redhat.thermostat:thermostat-vm-compiler-distribution</include>-->
 <!--        <include>com.redhat.thermostat:thermostat-vm-cpu-distribution</include>-->
 <!--        <include>com.redhat.thermostat:thermostat-vm-heap-analysis-distribution</include>-->
 <!--        <include>com.redhat.thermostat:thermostat-vm-jmx-distribution</include>-->
-        <include>com.redhat.thermostat:thermostat-commands-distribution</include>
-        <include>com.redhat.thermostat:thermostat-killvm-distribution</include>
 <!--        <include>com.redhat.thermostat:thermostat-vm-profiler-distribution</include>-->
 <!--        <include>com.redhat.thermostat:thermostat-vm-numa-distribution</include>-->
       </includes>
--- a/distribution/pom.xml	Mon Sep 18 14:04:16 2017 +0200
+++ b/distribution/pom.xml	Fri Sep 22 10:10:52 2017 -0400
@@ -282,7 +282,6 @@
               <goal>single</goal>
             </goals>
           </execution>
-<!-- TODO Uncomment once Byteman plugin is ported to use web-gateway
           <execution>
             <id>assemble-all-plugin-libs</id>
             <configuration>
@@ -296,7 +295,7 @@
             <goals>
               <goal>single</goal>
             </goals>
-          </execution>-->
+          </execution>
           <execution>
             <id>assemble-scripts</id>
             <configuration>
@@ -429,7 +428,6 @@
     <dependency>
       <groupId>com.redhat.thermostat</groupId>
       <artifactId>jnr-x86asm</artifactId>
-      <version>${jnr-x86asm.version}</version>
     </dependency>
     <dependency>
       <groupId>com.redhat.thermostat</groupId>
@@ -521,24 +519,24 @@
       <version>${project.version}</version>
       <type>zip</type>
     </dependency>
-    <!--<dependency>-->
-      <!--<groupId>com.redhat.thermostat</groupId>-->
-      <!--<artifactId>thermostat-numa-distribution</artifactId>-->
-      <!--<version>${project.version}</version>-->
-      <!--<type>zip</type>-->
-    <!--</dependency>-->
     <!-- thermostat-vm-byteman-distribution does not depend on
          thermostat-vm-byteman-helper. List it explicitly so
          that copy deps works. -->
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-byteman-helper-distro</artifactId>
+      <version>${project.version}</version>
+      <type>zip</type>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-byteman-distribution</artifactId>
+      <version>${project.version}</version>
+      <type>zip</type>
+    </dependency>
     <!--<dependency>-->
       <!--<groupId>com.redhat.thermostat</groupId>-->
-      <!--<artifactId>thermostat-vm-byteman-helper-distro</artifactId>-->
-      <!--<version>${project.version}</version>-->
-      <!--<type>zip</type>-->
-    <!--</dependency>-->
-    <!--<dependency>-->
-      <!--<groupId>com.redhat.thermostat</groupId>-->
-      <!--<artifactId>thermostat-vm-byteman-distribution</artifactId>-->
+      <!--<artifactId>thermostat-numa-distribution</artifactId>-->
       <!--<version>${project.version}</version>-->
       <!--<type>zip</type>-->
     <!--</dependency>-->
--- a/plugins/pom.xml	Mon Sep 18 14:04:16 2017 +0200
+++ b/plugins/pom.xml	Fri Sep 22 10:10:52 2017 -0400
@@ -62,7 +62,7 @@
     <module>vm-io</module>
     <module>vm-memory</module>
     <module>commands</module>
-    <!--<module>vm-byteman</module>-->
+    <module>vm-byteman</module>
     <!--<module>vm-cpu</module>-->
     <!--<module>vm-classstat</module>-->
     <!--<module>vm-compiler</module>-->
--- a/plugins/vm-byteman/agent/pom.xml	Mon Sep 18 14:04:16 2017 +0200
+++ b/plugins/vm-byteman/agent/pom.xml	Fri Sep 22 10:10:52 2017 -0400
@@ -46,26 +46,6 @@
   <artifactId>thermostat-vm-byteman-agent</artifactId>
   <packaging>bundle</packaging>
   <name>Thermostat VM Byteman Agent plugin</name>
-  <profiles>
-    <profile>
-      <id>skip-byteman-common-test-jar-dep-on-test-skip</id>
-      <activation>
-        <property>
-          <name>!maven.test.skip</name>
-        </property>
-      </activation>
-      <dependencies>
-        <!-- For JsonHelper test-only dependency -->
-        <dependency>
-          <groupId>com.redhat.thermostat</groupId>
-          <artifactId>thermostat-vm-byteman-common</artifactId>
-          <version>${project.version}</version>
-          <type>test-jar</type>
-          <scope>test</scope>
-        </dependency>
-      </dependencies>
-    </profile>
-  </profiles>
   <build>
     <plugins>
       <plugin>
@@ -76,10 +56,12 @@
           <instructions>
             <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
             <Bundle-SymbolicName>com.redhat.thermostat.vm.byteman.agent</Bundle-SymbolicName>
-            <Export-Package />
+            <Export-Package>
+              com.redhat.thermostat.vm.byteman.agent
+            </Export-Package>
             <Private-Package>
               com.redhat.thermostat.vm.byteman.agent.internal,
-              com.redhat.thermostat.vm.byteman.agent.internal.typeadapter
+              com.redhat.thermostat.vm.byteman.agent.internal.typeadapters,
             </Private-Package>
             <!-- Do not autogenerate uses clauses in Manifests -->
             <_nouses>true</_nouses>
@@ -128,12 +110,7 @@
     </dependency>
     <dependency>
       <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-vm-byteman-common</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-agent-command</artifactId>
+      <artifactId>thermostat-commands-agent</artifactId>
       <version>${project.version}</version>
     </dependency>
     <dependency>
@@ -153,6 +130,11 @@
     </dependency>
     <dependency>
       <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-jvm-overview-agent</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
       <artifactId>thermostat-common-test</artifactId>
       <version>${project.version}</version>
       <scope>test</scope>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/BytemanMetric.java	Fri Sep 22 10:10:52 2017 -0400
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2012-2017 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.byteman.agent;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonSyntaxException;
+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 BytemanMetric extends BasePojo implements TimeStampedPojo {
+
+    private static final Gson GSON = new GsonBuilder().serializeNulls().create();
+    public static final String MARKER_NAME = "marker";
+    public static final String TIMESTAMP_NAME = "timestamp";
+    public static final String DATA_NAME = "data";
+    private String jvmId;
+    private String marker;
+    private String payload;
+    private long timestamp;
+    
+    public BytemanMetric(String writerId) {
+        super(writerId);
+    }
+    
+    public BytemanMetric() {
+        this(null);
+    }
+    
+    @Persist
+    public String getJvmId() {
+        return jvmId;
+    }
+
+    @Persist
+    public void setJvmId(String jvmId) {
+        this.jvmId = jvmId;
+    }
+
+    /**
+     * Get the marker for this Byteman metric. A marker can be thought of a
+     * category for related metrics.
+     * 
+     * @return The marker for this metric.
+     */
+    @Persist
+    public String getMarker() {
+        return marker;
+    }
+
+    @Persist
+    public void setMarker(String marker) {
+        this.marker = marker;
+    }
+
+    @Persist
+    public void setTimeStamp(long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    @Persist
+    @Override
+    public long getTimeStamp() {
+        return timestamp;
+    }
+    
+    @Persist
+    public void setData(String json) {
+        this.payload = json;
+    }
+    
+    @Persist
+    public String getData() {
+        return payload;
+    }
+    
+    /**
+     * Get the metrics payload as raw JSON string. The payload is a JSON object
+     * in key, value form. Supported value types are {@code Boolean},
+     * {@code String} and {@code Double}.
+     * 
+     * @return The raw JSON string.
+     */
+    public String getDataAsJson() {
+        return getData();
+    }
+    
+    /**
+     * Get the metrics payload as parsed {@link Map}. Supported value types are
+     * {@code Boolean}, {@code String} and {@code Double}.
+     * 
+     * @return The parsed JSON payload as {@link Map}.
+     */
+    @SuppressWarnings("unchecked")
+    public Map<String, Object> getDataAsMap() {
+        try {
+            return (Map<String, Object>)GSON.fromJson(payload, HashMap.class);
+        } catch (JsonSyntaxException e) {
+            throw new RuntimeException("Payload not in expected format. Payload was: " + payload);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/VmBytemanDAO.java	Fri Sep 22 10:10:52 2017 -0400
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012-2017 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.byteman.agent;
+
+public interface VmBytemanDAO {
+
+    void addMetric(BytemanMetric metric);
+
+    void addBytemanStatus(VmBytemanStatus status);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/VmBytemanStatus.java	Fri Sep 22 10:10:52 2017 -0400
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2012-2017 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.byteman.agent;
+
+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 VmBytemanStatus extends BasePojo implements TimeStampedPojo {
+
+    private String jvmId;
+    private long timeStamp;
+    private String rule;
+    private int listenPort;
+    
+    public VmBytemanStatus(String writerId) {
+        super(writerId);
+    }
+    
+    public VmBytemanStatus() {
+        super(null);
+    }
+    
+    @Persist
+    public String getJvmId() {
+        return jvmId;
+    }
+
+    @Persist
+    public void setJvmId(String jvmId) {
+        this.jvmId = jvmId;
+    }
+    
+    @Persist
+    public void setTimeStamp(long timestamp) {
+        this.timeStamp = timestamp;
+    }
+
+    @Persist
+    @Override
+    public long getTimeStamp() {
+        return timeStamp;
+    }
+    
+    @Persist
+    public void setRule(String rule) {
+        this.rule = rule;
+    }
+    
+    @Persist
+    public String getRule() {
+        return rule;
+    }
+    
+    @Persist
+    public void setListenPort(int port) {
+        this.listenPort = port;
+    }
+    
+    @Persist
+    public int getListenPort() {
+        return listenPort;
+    }
+
+}
--- a/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManager.java	Mon Sep 18 14:04:16 2017 +0200
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManager.java	Fri Sep 22 10:10:52 2017 -0400
@@ -49,15 +49,15 @@
 
 import org.jboss.byteman.agent.submit.Submit;
 
+import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks;
 import com.redhat.thermostat.common.portability.ProcessUserInfo;
 import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder;
-import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks;
 import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.jvm.overview.agent.model.VmId;
 import com.redhat.thermostat.shared.config.CommonPaths;
-import com.redhat.thermostat.storage.core.VmId;
 import com.redhat.thermostat.storage.core.WriterID;
-import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO;
-import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus;
+import com.redhat.thermostat.vm.byteman.agent.VmBytemanDAO;
+import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus;
 
 /**
  * Manages attaching of the byteman agent as well as adding
@@ -65,18 +65,18 @@
  *
  */
 class BytemanAgentAttachManager {
-    
+
     private static final String BYTEMAN_PLUGIN_DIR = System.getProperty("thermostat.plugin", "vm-byteman");
     private static final String BYTEMAN_PLUGIN_LIBS_DIR = BYTEMAN_PLUGIN_DIR + File.separator + "plugin-libs";
     private static final String BYTEMAN_INSTALL_HOME = BYTEMAN_PLUGIN_LIBS_DIR + File.separator + "byteman-install";
     private static final String BYTEMAN_HELPER_DIR = BYTEMAN_PLUGIN_LIBS_DIR + File.separator + "thermostat-helper";
     private static final String BYTEMAN_HOME_PROPERTY = "org.jboss.byteman.home";
     private static final Logger logger = LoggingUtils.getLogger(BytemanAgentAttachManager.class);
-    
+
     // package-private for testing
     static final String THERMOSTAT_HELPER_SOCKET_NAME_PROPERTY = "org.jboss.byteman.thermostat.socketName";
     static List<String> helperJars;
-    
+
     private final SubmitHelper submit;
     private final FileSystemUtils fsUtils;
     private BytemanAttacher attacher;
@@ -89,7 +89,7 @@
         this.submit = new SubmitHelper();
         this.fsUtils = new FileSystemUtils();
     }
-    
+
     // for testing only
     BytemanAgentAttachManager(BytemanAttacher attacher, IPCEndpointsManager ipcManager, VmBytemanDAO vmBytemanDao, SubmitHelper submit,
                               WriterID writerId, ProcessUserInfoBuilder userInfoBuilder, FileSystemUtils fsUtils) {
@@ -101,7 +101,7 @@
         this.userInfoBuilder = userInfoBuilder;
         this.fsUtils = fsUtils;
     }
-    
+
     VmBytemanStatus attachBytemanToVm(VmId vmId, int vmPid) {
         logger.fine("Attaching byteman agent to VM '" + vmPid + "'");
         // Fail early if we can't determine process owner
@@ -125,11 +125,11 @@
         VmBytemanStatus status = new VmBytemanStatus(writerId.getWriterID());
         status.setListenPort(info.getAgentListenPort());
         status.setTimeStamp(System.currentTimeMillis());
-        status.setVmId(vmId.get());
-        vmBytemanDao.addOrReplaceBytemanStatus(status);
+        status.setJvmId(vmId.get());
+        vmBytemanDao.addBytemanStatus(status);
         return status;
     }
-    
+
     private UserPrincipal getUserPrincipalForPid(int vmPid) {
         UserPrincipal principal = null;
         ProcessUserInfo info = userInfoBuilder.build(vmPid);
@@ -170,12 +170,12 @@
     private boolean addThermostatHelperJarsToClasspath(BytemanAgentInfo info) {
         return submit.addJarsToSystemClassLoader(helperJars, info);
     }
-    
+
     static List<String> initListOfHelperJars(CommonPaths commonPaths) {
         File bytemanHelperDir = new File(commonPaths.getSystemPluginRoot(), BYTEMAN_HELPER_DIR);
         return initListOfHelperJars(bytemanHelperDir);
     }
-    
+
     // package private for testing
     static synchronized List<String> initListOfHelperJars(File helperDir) {
         if (helperJars == null) {
@@ -187,7 +187,7 @@
         }
         return helperJars;
     }
-    
+
     static synchronized void setBytemanHomeProperty(CommonPaths commonPaths) {
         final String bytemanHomePropVal = System.getProperty(BYTEMAN_HOME_PROPERTY);
         if (bytemanHomePropVal == null) {
@@ -197,7 +197,7 @@
             System.setProperty(BYTEMAN_HOME_PROPERTY, bytemanHome);
         }
     }
-    
+
     void setAttacher(BytemanAttacher attacher) {
         this.attacher = attacher;
     }
@@ -222,9 +222,9 @@
     void setUserInfoBuilder(ProcessUserInfoBuilder userInfoBuilder) {
         this.userInfoBuilder = userInfoBuilder;
     }
-    
+
     static class SubmitHelper {
-        
+
         boolean addJarsToSystemClassLoader(List<String> jars, BytemanAgentInfo info) {
             Submit submit = new Submit(null /* localhost */, info.getAgentListenPort());
             try {
@@ -236,7 +236,7 @@
                 return false;
             }
         }
-        
+
         boolean setSystemProperties(Properties properties, BytemanAgentInfo info) {
             Submit submit = new Submit(null /* localhost */, info.getAgentListenPort());
             try {
@@ -248,14 +248,14 @@
                 return false;
             }
         }
-        
+
     }
-    
+
     static class FileSystemUtils {
-        
+
         UserPrincipalLookupService getUserPrincipalLookupService() {
             return FileSystems.getDefault().getUserPrincipalLookupService();
         }
-        
+
     }
 }
--- a/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiver.java	Mon Sep 18 14:04:16 2017 +0200
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiver.java	Fri Sep 22 10:10:52 2017 -0400
@@ -48,9 +48,9 @@
 import com.redhat.thermostat.agent.ipc.server.IPCMessage;
 import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks;
 import com.redhat.thermostat.common.utils.LoggingUtils;
-import com.redhat.thermostat.vm.byteman.common.BytemanMetric;
-import com.redhat.thermostat.vm.byteman.common.BytemanMetricTypeAdapterFactory;
-import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO;
+import com.redhat.thermostat.vm.byteman.agent.BytemanMetric;
+import com.redhat.thermostat.vm.byteman.agent.VmBytemanDAO;
+import com.redhat.thermostat.vm.byteman.agent.internal.typeadapters.BytemanTypeAdapterFactory;
 
 class BytemanMetricsReceiver implements ThermostatIPCCallbacks {
     
@@ -63,7 +63,7 @@
         this.dao = dao;
         this.socketId = socketId;
         this.gson = new GsonBuilder()
-                .registerTypeAdapterFactory(new BytemanMetricTypeAdapterFactory())
+                .registerTypeAdapterFactory(new BytemanTypeAdapterFactory())
                 .serializeNulls()
                 .disableHtmlEscaping()
                 .create();
@@ -86,7 +86,7 @@
         List<BytemanMetric> listOfMetrics = new ArrayList<>();
         for (BytemanMetric m: metrics) {
             m.setAgentId(socketId.getAgentId());
-            m.setVmId(socketId.getVmId());
+            m.setJvmId(socketId.getVmId());
             listOfMetrics.add(m);
         }
         return listOfMetrics;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequest.java	Fri Sep 22 10:10:52 2017 -0400
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2012-2017 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.byteman.agent.internal;
+
+public class BytemanRequest {
+
+    public static enum RequestAction {
+        LOAD_RULES(0),
+        UNLOAD_RULES(1),
+        ;
+
+        private int actionId;
+
+        private RequestAction(int id) {
+            this.actionId = id;
+        }
+
+        public static RequestAction fromIntString(String id) {
+            int intId;
+            try {
+                intId = Integer.parseInt(id);
+            } catch (NumberFormatException e) {
+                throw new IllegalArgumentException("Unknown action: " + id);
+            }
+            switch(intId) {
+            case(0): return LOAD_RULES;
+            case(1): return UNLOAD_RULES;
+            default:
+                throw new IllegalArgumentException("Unknown action: " + id);
+            }
+        }
+
+        int getActionId() {
+            return actionId;
+        }
+
+    }
+
+    public static final String VM_PID_PARAM_NAME = "vm-pid";
+    public static final String ACTION_PARAM_NAME = "byteman-action";
+    public static final String LISTEN_PORT_PARAM_NAME = "listen-port";
+    public static final String RULE_PARAM_NAME = "byteman-rule";
+    public static final int NOT_ATTACHED_PORT = -1;
+
+}
--- a/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiver.java	Mon Sep 18 14:04:16 2017 +0200
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiver.java	Fri Sep 22 10:10:52 2017 -0400
@@ -44,8 +44,6 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder;
-import com.redhat.thermostat.common.portability.ProcessUserInfoBuilderFactory;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Reference;
@@ -53,21 +51,22 @@
 import org.jboss.byteman.agent.submit.ScriptText;
 import org.jboss.byteman.agent.submit.Submit;
 
-import com.redhat.thermostat.agent.command.RequestReceiver;
 import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
-import com.redhat.thermostat.common.portability.linux.ProcDataSource;
+import com.redhat.thermostat.commands.agent.receiver.RequestReceiver;
+import com.redhat.thermostat.commands.model.AgentRequest;
+import com.redhat.thermostat.commands.model.WebSocketResponse;
+import com.redhat.thermostat.commands.model.WebSocketResponse.ResponseType;
+import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder;
+import com.redhat.thermostat.common.portability.ProcessUserInfoBuilderFactory;
 import com.redhat.thermostat.common.portability.UserNameUtil;
-import com.redhat.thermostat.common.command.Request;
-import com.redhat.thermostat.common.command.Response;
-import com.redhat.thermostat.common.command.Response.ResponseType;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
 import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.jvm.overview.agent.model.VmId;
 import com.redhat.thermostat.shared.config.CommonPaths;
-import com.redhat.thermostat.storage.core.VmId;
 import com.redhat.thermostat.storage.core.WriterID;
-import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO;
-import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus;
-import com.redhat.thermostat.vm.byteman.common.command.BytemanRequest;
-import com.redhat.thermostat.vm.byteman.common.command.BytemanRequest.RequestAction;
+import com.redhat.thermostat.vm.byteman.agent.VmBytemanDAO;
+import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus;
+import com.redhat.thermostat.vm.byteman.agent.internal.BytemanRequest.RequestAction;
 
 /**
  * Receiver class for Byteman action command channel requests.
@@ -75,105 +74,109 @@
  */
 @Component
 @Service(value = RequestReceiver.class)
-@Property(name = "servicename", value = "com.redhat.thermostat.vm.byteman.agent.internal.BytemanRequestReceiver")
+@Property(name = "servicename", value = BytemanRequestReceiver.ACTION_NAME)
 public class BytemanRequestReceiver implements RequestReceiver {
-    
+
+    public static final String ACTION_NAME = "byteman";
     private static final int ILLEGAL_INT_VAL = -1;
     private static final int ILLEGAL_PORT = -2;
     private static final Logger logger = LoggingUtils.getLogger(BytemanRequestReceiver.class);
-    private static final Response ERROR_RESPONSE = new Response(ResponseType.ERROR);
-    private static final Response OK_RESPONSE = new Response(ResponseType.OK);
-    
+
     private final BytemanAgentAttachManager attachManager;
-    
+
     public BytemanRequestReceiver() {
         this(new BytemanAgentAttachManager());
     }
-    
+
     // package-private for testing
     BytemanRequestReceiver(BytemanAgentAttachManager attachManager) {
         this.attachManager = attachManager;
     }
-    
+
     @Reference
     private VmBytemanDAO vmBytemanDao;
-    
+
     @Reference
     private WriterID writerId;
-    
+
     @Reference
     private CommonPaths commonPaths;
-    
+
     @Reference
     private AgentIPCService agentIpcService;
-    
+
     @Reference
     private UserNameUtil userNameUtil;
-    
+
     ////////////////////////////////////////////////
     // methods used by DS
     ////////////////////////////////////////////////
-    
+
     protected void bindWriterId(WriterID writerId) {
         this.writerId = writerId;
         attachManager.setWriterId(writerId);
     }
-    
+
     protected void unbindWriterId(WriterID writerId) {
         this.writerId = null;
         attachManager.setWriterId(null);
     }
-    
+
     protected void bindVmBytemanDao(VmBytemanDAO dao) {
         this.vmBytemanDao = dao;
         attachManager.setVmBytemanDao(dao);
     }
-    
+
     protected void unbindVmBytemanDao(VmBytemanDAO dao) {
         this.vmBytemanDao = null;
         attachManager.setVmBytemanDao(null);
     }
-    
+
     protected void bindCommonPaths(CommonPaths paths) {
         attachManager.setPaths(paths);
     }
-    
+
     protected void unbindCommonPaths(CommonPaths paths) {
         // helper jars don't strictly need unsetting so we don't
         // call setPaths(null)
     }
-    
+
     protected void bindAgentIpcService(AgentIPCService ipcService) {
         IPCEndpointsManager ipcEndpointsManager = new IPCEndpointsManager(ipcService);
         attachManager.setIpcManager(ipcEndpointsManager);
         BytemanAttacher bmAttacher = new BytemanAttacher(ipcService);
         attachManager.setAttacher(bmAttacher);
     }
-    
+
     protected void unbindAgentIpcService(AgentIPCService ipcService) {
         attachManager.setIpcManager(null);
         attachManager.setAttacher(null);
     }
-    
+
     protected void bindUserNameUtil(UserNameUtil userNameUtil) {
         ProcessUserInfoBuilder userInfoBuilder = ProcessUserInfoBuilderFactory.createBuilder(new ProcDataSource(), userNameUtil);
         attachManager.setUserInfoBuilder(userInfoBuilder);
     }
-    
+
     protected void unbindUserNameUtil(UserNameUtil userNameUtil) {
         attachManager.setUserInfoBuilder(null);
     }
-    
+
     ////////////////////////////////////////////////
     // end methods used by DS
     ////////////////////////////////////////////////
-    
+
     @Override
-    public Response receive(Request request) {
-        String vmId = request.getParameter(BytemanRequest.VM_ID_PARAM_NAME);
-        String actionStr = request.getParameter(BytemanRequest.ACTION_PARAM_NAME);
-        String portStr = request.getParameter(BytemanRequest.LISTEN_PORT_PARAM_NAME);
-        String vmPidStr = request.getParameter(BytemanRequest.VM_PID_PARAM_NAME);
+    public WebSocketResponse receive(AgentRequest request) {
+        // Sanity check. We should never get requests outside our action domain.
+        if (!ACTION_NAME.equals(request.getAction())) {
+            logger.severe("Received action '" + request.getAction() + "' for receiver '" + ACTION_NAME + "'");
+            return new WebSocketResponse(request.getSequenceId(), ResponseType.ERROR);
+        }
+        String vmId = request.getJvmId();
+        String actionStr = request.getParam(BytemanRequest.ACTION_PARAM_NAME);
+        String portStr = request.getParam(BytemanRequest.LISTEN_PORT_PARAM_NAME);
+        String vmPidStr = request.getParam(BytemanRequest.VM_PID_PARAM_NAME);
         RequestAction action;
         int vmPid;
         int port;
@@ -181,35 +184,35 @@
             action = RequestAction.fromIntString(actionStr);
         } catch (IllegalArgumentException e) {
             logger.log(Level.WARNING, "Illegal action received", e);
-            return ERROR_RESPONSE;
+            return error(request.getSequenceId());
         }
         if ((vmPid = tryParseInt(vmPidStr, "VM pid not a number!", ILLEGAL_INT_VAL)) == ILLEGAL_INT_VAL) {
-            return ERROR_RESPONSE;
+            return error(request.getSequenceId());
         }
         if ((port = tryParseInt(portStr, "Listen port not an integer!", ILLEGAL_PORT)) == ILLEGAL_PORT) {
-            return ERROR_RESPONSE;
+            return error(request.getSequenceId());
         }
         if (!isPortValid(port)) {
             logger.warning("Listen port is invalid. Got value '" + port + "'");
-            return ERROR_RESPONSE;
+            return error(request.getSequenceId());
         }
         logger.fine("Processing request for vmId: " + vmId + ", pid: " + vmPid + ", Action: " + action + ", port: " + portStr);
-        Response response = null;
+        WebSocketResponse response;
         switch(action) {
         case LOAD_RULES:
-            String rule = request.getParameter(BytemanRequest.RULE_PARAM_NAME);
-            response = attachAndLoadRules(port, new VmId(vmId), vmPid, rule);
+            String rule = request.getParam(BytemanRequest.RULE_PARAM_NAME);
+            response = attachAndLoadRules(port, new VmId(vmId), vmPid, rule, request.getSequenceId());
             break;
         case UNLOAD_RULES:
-            response = unloadRules(port, new VmId(vmId));
+            response = unloadRules(port, new VmId(vmId), request.getSequenceId());
             break;
         default:
             logger.warning("Unknown action: " + action);
-            return ERROR_RESPONSE;
+            return error(request.getSequenceId());
         }
         return response;
     }
-    
+
     private boolean isPortValid(int port) {
         if (port <= 0) {
             // only agent not attached is a valid but negative value
@@ -227,15 +230,15 @@
         }
     }
 
-    private Response attachAndLoadRules(int listenPort, VmId vmId, int vmPid, String bytemanRules) {
+    private WebSocketResponse attachAndLoadRules(int listenPort, VmId vmId, int vmPid, String bytemanRules, long sequenceId) {
         int actualListenPort = attachAgentIfRequired(listenPort, vmId, vmPid);
         if (actualListenPort == BytemanRequest.NOT_ATTACHED_PORT) {
             logger.log(Level.WARNING, "Failed to attach byteman agent. Cannot load rules.");
-            return ERROR_RESPONSE;
+            return error(sequenceId);
         }
-        return loadRules(actualListenPort, vmId, bytemanRules);
+        return loadRules(actualListenPort, vmId, bytemanRules, sequenceId);
     }
-    
+
     private int attachAgentIfRequired(int listenPort, VmId vmId, int vmPid) {
         if (isAgentAttached(listenPort)) {
             return listenPort;
@@ -247,14 +250,14 @@
         }
         return actualListenPort;
     }
-    
+
     private boolean isAgentAttached(int listenPort) {
         // if we come here with a negative port value we know the agent has not
         // yet been attached.
         return listenPort != BytemanRequest.NOT_ATTACHED_PORT;
     }
 
-    private Response loadRules(int listenPort, VmId vmId, String bytemanRules) {
+    private WebSocketResponse loadRules(int listenPort, VmId vmId, String bytemanRules, final long sequence) {
         Submit submit = getSubmit(listenPort);
         try {
             List<ScriptText> existingScripts = submit.getAllScripts();
@@ -269,39 +272,48 @@
             status.setListenPort(listenPort);
             status.setRule(bytemanRules);
             status.setTimeStamp(System.currentTimeMillis());
-            status.setVmId(vmId.get());
-            vmBytemanDao.addOrReplaceBytemanStatus(status);
-            return OK_RESPONSE;
+            status.setJvmId(vmId.get());
+            vmBytemanDao.addBytemanStatus(status);
+            return ok(sequence);
         } catch (Exception e) {
             logger.log(Level.WARNING, "Failed to submit byteman rules", e);
-            return ERROR_RESPONSE;
+            return error(sequence);
         }
     }
 
-    private Response unloadRules(int listenPort, VmId vmId) {
+    private WebSocketResponse unloadRules(int listenPort, VmId vmId, long sequence) {
         Submit submit = getSubmit(listenPort);
         try {
             List<ScriptText> list = submit.getAllScripts();
             // Avoid no scripts to delete errors
             if (!list.isEmpty()) {
-                submit.deleteAllRules();
+                String deleteAllResult = submit.deleteAllRules();
+                logger.info("Removed all byteman rules for VM with id '" + vmId.get() + "' with result: " + deleteAllResult);
                 // update the corresponding status in storage
                 VmBytemanStatus newStatus = new VmBytemanStatus(writerId.getWriterID());
                 newStatus.setListenPort(listenPort);
                 newStatus.setRule(null);
                 newStatus.setTimeStamp(System.currentTimeMillis());
-                newStatus.setVmId(vmId.get());
-                vmBytemanDao.addOrReplaceBytemanStatus(newStatus);
+                newStatus.setJvmId(vmId.get());
+                vmBytemanDao.addBytemanStatus(newStatus);
             }
-            return OK_RESPONSE;
+            return ok(sequence);
         } catch (Exception e) {
             logger.log(Level.WARNING, "Failed to delete rules", e);
-            return ERROR_RESPONSE;
+            return error(sequence);
         }
     }
 
+    private WebSocketResponse error(long sequence) {
+        return new WebSocketResponse(sequence, ResponseType.ERROR);
+    }
+
+    private WebSocketResponse ok(long sequence) {
+        return new WebSocketResponse(sequence, ResponseType.OK);
+    }
+
     protected Submit getSubmit(int listenPort) {
         return new Submit(null /* localhost */, listenPort);
     }
-    
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanDAOImpl.java	Fri Sep 22 10:10:52 2017 -0400
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2012-2017 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.byteman.agent.internal;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+
+import com.google.gson.Gson;
+import com.redhat.thermostat.agent.http.HttpRequestService;
+import com.redhat.thermostat.common.config.experimental.ConfigurationInfoSource;
+import com.redhat.thermostat.common.plugin.PluginConfiguration;
+import com.redhat.thermostat.common.plugin.SystemID;
+import com.redhat.thermostat.vm.byteman.agent.BytemanMetric;
+import com.redhat.thermostat.vm.byteman.agent.VmBytemanDAO;
+import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus;
+import com.redhat.thermostat.vm.byteman.agent.internal.typeadapters.GsonCreator;
+
+@Component
+@Service(value = VmBytemanDAO.class)
+public class VmBytemanDAOImpl implements VmBytemanDAO {
+
+    private static final String PLUGIN_ID = "vm-byteman";
+
+    private final ConfigurationCreator configCreator;
+    private final GsonCreator gsonCreator;
+
+    @Reference
+    private HttpRequestService httpRequestService;
+    @Reference
+    private ConfigurationInfoSource configInfoSource;
+    @Reference
+    private SystemID systemId;
+
+    private VmBytemanMetricsStore metricsStore;
+
+    private VmBytemanStatusStore statusStore;
+
+    public VmBytemanDAOImpl() {
+        this(new ConfigurationCreator(), new GsonCreator());
+    }
+
+    VmBytemanDAOImpl(ConfigurationCreator configCreator, GsonCreator creator) {
+        this.configCreator = configCreator;
+        this.gsonCreator = creator;
+    }
+
+    @Activate
+    private void activate() {
+        PluginConfiguration config = configCreator.create(configInfoSource);
+        Gson gson = gsonCreator.create();
+        metricsStore = new VmBytemanMetricsStore(httpRequestService, config, systemId, gson);
+        statusStore = new VmBytemanStatusStore(httpRequestService, config, systemId, gson);
+    }
+
+    @Override
+    public void addMetric(final BytemanMetric metric) {
+        metricsStore.put(metric);
+    }
+
+    @Override
+    public void addBytemanStatus(final VmBytemanStatus status) {
+        statusStore.put(status);
+    }
+
+    // For Testing purposes
+    static class ConfigurationCreator {
+
+        PluginConfiguration create(ConfigurationInfoSource source) {
+            return new PluginConfiguration(source, PLUGIN_ID);
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanMetricsStore.java	Fri Sep 22 10:10:52 2017 -0400
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2012-2017 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.byteman.agent.internal;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+import java.util.logging.Logger;
+
+import com.google.gson.Gson;
+import com.redhat.thermostat.agent.http.HttpRequestService;
+import com.redhat.thermostat.common.plugin.PluginConfiguration;
+import com.redhat.thermostat.common.plugin.PluginDAOBase;
+import com.redhat.thermostat.common.plugin.SystemID;
+import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.vm.byteman.agent.BytemanMetric;
+
+class VmBytemanMetricsStore extends PluginDAOBase<BytemanMetric> {
+
+    private static final String METRICS_PATH = "metrics";
+    private static final Logger LOGGER = LoggingUtils.getLogger(VmBytemanMetricsStore.class);
+    private final HttpRequestService httpRequestService;
+    private final PluginConfiguration pluginConfig;
+    private final SystemID systemId;
+    private final Gson gson;
+
+    VmBytemanMetricsStore(HttpRequestService httpRequestService,
+                          PluginConfiguration pluginConfig,
+                          SystemID systemId,
+                          Gson gson) {
+        this.httpRequestService = httpRequestService;
+        this.pluginConfig = pluginConfig;
+        this.systemId = systemId;
+        this.gson = gson;
+    }
+
+    @Override
+    protected String toJsonString(BytemanMetric obj) throws IOException {
+        List<BytemanMetric> bytemanMetrics = Arrays.asList(obj);
+        return gson.toJson(bytemanMetrics);
+    }
+
+    @Override
+    protected HttpRequestService getHttpRequestService() {
+        return httpRequestService;
+    }
+
+    @Override
+    protected PluginConfiguration getConfig() {
+        return pluginConfig;
+    }
+
+    @Override
+    protected URI getPostURI(URI basepath, BytemanMetric obj) {
+        return basepath.resolve(METRICS_PATH + "/systems/" + systemId.getSystemID() + "/jvms/" + obj.getJvmId());
+    }
+
+    @Override
+    protected Logger getLogger() {
+        return LOGGER;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/VmBytemanStatusStore.java	Fri Sep 22 10:10:52 2017 -0400
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2012-2017 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.byteman.agent.internal;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.google.gson.Gson;
+import com.redhat.thermostat.agent.http.HttpRequestService;
+import com.redhat.thermostat.common.plugin.PluginConfiguration;
+import com.redhat.thermostat.common.plugin.PluginDAOBase;
+import com.redhat.thermostat.common.plugin.SystemID;
+import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus;
+
+class VmBytemanStatusStore extends PluginDAOBase<VmBytemanStatus> {
+
+    private static final String STATUS_PATH = "status";
+    private static final Logger LOGGER = LoggingUtils.getLogger(VmBytemanStatusStore.class);
+    private final HttpRequestService httpRequestService;
+    private final PluginConfiguration pluginConfig;
+    private final SystemID systemId;
+    private final Gson gson;
+
+    VmBytemanStatusStore(HttpRequestService httpRequestService,
+                          PluginConfiguration pluginConfig,
+                          SystemID systemId,
+                          Gson gson) {
+        this.httpRequestService = httpRequestService;
+        this.pluginConfig = pluginConfig;
+        this.systemId = systemId;
+        this.gson = gson;
+    }
+
+    @Override
+    protected String toJsonString(VmBytemanStatus obj) throws IOException {
+        List<VmBytemanStatus> vmBytemanStatuses = Arrays.asList(obj);
+        return gson.toJson(vmBytemanStatuses);
+    }
+
+    @Override
+    protected HttpRequestService getHttpRequestService() {
+        return httpRequestService;
+    }
+
+    @Override
+    protected PluginConfiguration getConfig() {
+        return pluginConfig;
+    }
+
+    @Override
+    protected URI getPostURI(URI basepath, VmBytemanStatus obj) {
+        return basepath.resolve(STATUS_PATH + "/systems/" + systemId.getSystemID() + "/jvms/" + obj.getJvmId());
+    }
+
+    @Override
+    protected Logger getLogger() {
+        return LOGGER;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapters/BytemanMetricTypeAdapter.java	Fri Sep 22 10:10:52 2017 -0400
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2012-2017 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.byteman.agent.internal.typeadapters;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+import com.redhat.thermostat.vm.byteman.agent.BytemanMetric;
+
+class BytemanMetricTypeAdapter extends TypeAdapter<BytemanMetric> {
+
+    private static final String TYPE_LONG = "$numberLong";
+    private static final String VM_ID = "jvmId";
+    private static final String AGENT_ID = "agentId";
+    private static final String MARKER = "marker";
+    private static final String JSON_PAYLOAD = "payload";
+    private static final String TIMESTAMP = "timeStamp";
+
+    private final Gson gson;
+
+    BytemanMetricTypeAdapter(Gson gson) {
+        this.gson = gson;
+    }
+
+    @Override
+    public BytemanMetric read(JsonReader reader) throws IOException {
+        // handle null
+        if (reader.peek() == JsonToken.NULL) {
+            reader.nextNull();
+            return null;
+        }
+
+        reader.beginObject();
+        BytemanMetric metric = parseMetric(reader);
+        reader.endObject();
+        return metric;
+    }
+
+    @Override
+    public void write(JsonWriter out, BytemanMetric metric) throws IOException {
+        out.beginObject();
+        out.name(AGENT_ID);
+        out.value(metric.getAgentId());
+        out.name(VM_ID);
+        out.value(metric.getJvmId());
+        out.name(MARKER);
+        out.value(metric.getMarker());
+        out.name(JSON_PAYLOAD);
+        out.value(metric.getDataAsJson());
+        out.name(TIMESTAMP);
+        writeLong(out, metric.getTimeStamp());
+        out.endObject();
+    }
+
+    private void writeLong(JsonWriter out, long value) throws IOException {
+        // Write MongoDB representation of a Long
+        out.beginObject();
+        out.name(TYPE_LONG);
+        out.value(String.valueOf(value));
+        out.endObject();
+    }
+
+    @SuppressWarnings("unchecked")
+    private BytemanMetric parseMetric(JsonReader reader) throws IOException {
+        Map<String, Object> values = new HashMap<>();
+        while (reader.hasNext()) {
+            String name = reader.nextName();
+            switch(name) {
+                case BytemanMetric.MARKER_NAME:
+                    values.put(BytemanMetric.MARKER_NAME, reader.nextString());
+                    break;
+                case BytemanMetric.TIMESTAMP_NAME:
+                    values.put(BytemanMetric.TIMESTAMP_NAME, Long.valueOf(reader.nextString()));
+                    break;
+            case BytemanMetric.DATA_NAME:
+                Map<String, Object> data = getDataValues(reader);
+                values.put(BytemanMetric.DATA_NAME, data);
+                break;
+            default:
+                throw new IllegalStateException("Unknown name: '" + name + "'");
+            }
+        }
+        BytemanMetric metric = new BytemanMetric();
+        metric.setMarker((String)values.get(BytemanMetric.MARKER_NAME));
+        metric.setTimeStamp((Long)values.get(BytemanMetric.TIMESTAMP_NAME));
+        metric.setData(mapToJson((Map<String, Object>)values.get(BytemanMetric.DATA_NAME)));
+        return metric;
+    }
+
+    private String mapToJson(Map<String, Object> map) {
+        return gson.toJson(map, HashMap.class);
+    }
+
+    private Map<String, Object> getDataValues(JsonReader reader) throws IOException {
+        return gson.fromJson(reader, HashMap.class);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapters/BytemanTypeAdapterFactory.java	Fri Sep 22 10:10:52 2017 -0400
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2012-2017 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.byteman.agent.internal.typeadapters;
+
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.redhat.thermostat.vm.byteman.agent.BytemanMetric;
+import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus;
+
+public class BytemanTypeAdapterFactory implements TypeAdapterFactory {
+
+    @Override
+    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
+        Class<?> rawType = type.getRawType();
+        if (rawType == BytemanMetric.class) {
+            @SuppressWarnings("unchecked")
+            TypeAdapter<T> ta = (TypeAdapter<T>)new BytemanMetricTypeAdapter(gson);
+            return ta;
+        } else if (rawType == VmBytemanStatus.class) {
+            @SuppressWarnings("unchecked")
+            TypeAdapter<T> ta = (TypeAdapter<T>)new VmBytemanStatusTypeAdapter();
+            return ta;
+        }
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapters/GsonCreator.java	Fri Sep 22 10:10:52 2017 -0400
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012-2017 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.byteman.agent.internal.typeadapters;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class GsonCreator {
+
+    public Gson create() {
+        GsonBuilder builder = new GsonBuilder();
+        builder.registerTypeAdapterFactory(new BytemanTypeAdapterFactory());
+        builder.serializeNulls();
+        return builder.create();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapters/VmBytemanStatusTypeAdapter.java	Fri Sep 22 10:10:52 2017 -0400
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2012-2017 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.byteman.agent.internal.typeadapters;
+
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus;
+
+import java.io.IOException;
+
+public class VmBytemanStatusTypeAdapter extends TypeAdapter<VmBytemanStatus> {
+
+    private static final String TYPE_LONG = "$numberLong";
+    private static final String VM_ID = "jvmId";
+    private static final String AGENT_ID = "agentId";
+    private static final String TIMESTAMP = "timeStamp";
+    private static final String RULE = "rule";
+    private static final String LISTEN_PORT = "listenPort";
+
+    @Override
+    public VmBytemanStatus read(JsonReader in) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void write(JsonWriter out, VmBytemanStatus status) throws IOException {
+        out.beginObject();
+        out.name(AGENT_ID);
+        out.value(status.getAgentId());
+        out.name(VM_ID);
+        out.value(status.getJvmId());
+        out.name(TIMESTAMP);
+        writeLong(out, status.getTimeStamp());
+        out.name(RULE);
+        out.value(status.getRule());
+        out.name(LISTEN_PORT);
+        out.value(status.getListenPort());
+        out.endObject();
+    }
+
+    private void writeLong(JsonWriter out, long value) throws IOException {
+        // Write MongoDB representation of a Long
+        out.beginObject();
+        out.name(TYPE_LONG);
+        out.value(String.valueOf(value));
+        out.endObject();
+    }
+}
--- a/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManagerTest.java	Mon Sep 18 14:04:16 2017 +0200
+++ b/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManagerTest.java	Fri Sep 22 10:10:52 2017 -0400
@@ -63,26 +63,26 @@
 
 import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
 import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks;
+import com.redhat.thermostat.common.portability.ProcessChecker;
 import com.redhat.thermostat.common.portability.ProcessUserInfo;
 import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder;
-import com.redhat.thermostat.common.portability.ProcessChecker;
-import com.redhat.thermostat.storage.core.VmId;
+import com.redhat.thermostat.jvm.overview.agent.model.VmId;
 import com.redhat.thermostat.storage.core.WriterID;
+import com.redhat.thermostat.vm.byteman.agent.VmBytemanDAO;
+import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus;
 import com.redhat.thermostat.vm.byteman.agent.internal.BytemanAgentAttachManager.FileSystemUtils;
 import com.redhat.thermostat.vm.byteman.agent.internal.BytemanAgentAttachManager.SubmitHelper;
 import com.redhat.thermostat.vm.byteman.agent.internal.BytemanAttacher.BtmInstallHelper;
-import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO;
-import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus;
 
 public class BytemanAgentAttachManagerTest {
-    
+
     private static final VmId SOME_VM_ID = new VmId("some-vm-id");
     private static final int SOME_VM_PID = 99910;
     private static final String SOME_AGENT_ID = "some-agent-id";
     private static final int SOME_UID = 1111;
     private static final String SOME_USERNAME = "someUser";
     private static final BytemanAgentInfo SOME_SUCCESS_BYTEMAN_INFO = new BytemanAgentInfo(SOME_VM_PID, 3344, null, SOME_VM_ID.get(), SOME_AGENT_ID, false, false);
-    
+
     private BytemanAgentAttachManager manager;
     private IPCEndpointsManager ipcManager;
     private VmBytemanDAO vmBytemanDao;
@@ -90,7 +90,7 @@
     private BytemanAttacher bytemanAttacher;
     private ProcessUserInfoBuilder userInfoBuilder;
     private UserPrincipalLookupService lookup;
-    
+
     @Before
     public void setup() throws IOException {
         ipcManager = mock(IPCEndpointsManager.class);
@@ -101,7 +101,7 @@
         when(writerId.getWriterID()).thenReturn(SOME_AGENT_ID);
         userInfoBuilder = mock(ProcessUserInfoBuilder.class);
         FileSystemUtils fsUtils = mock(FileSystemUtils.class);
-        
+
         ProcessUserInfo info = new ProcessUserInfo(SOME_UID, SOME_USERNAME);
         when(userInfoBuilder.build(SOME_VM_PID)).thenReturn(info);
         lookup = mock(UserPrincipalLookupService.class);
@@ -110,7 +110,7 @@
         when(lookup.lookupPrincipalByName(SOME_USERNAME)).thenReturn(owner);
         manager = new BytemanAgentAttachManager(bytemanAttacher, ipcManager, vmBytemanDao, submit, writerId, userInfoBuilder, fsUtils);
     }
-    
+
     @After
     public void tearDown() {
         BytemanAgentAttachManager.helperJars = null;
@@ -125,42 +125,42 @@
         int listenPort = 9881;
         BytemanAgentInfo bytemanAgentInfo = new BytemanAgentInfo(vmPid, listenPort, null, workingVmId, agentId, false, false);
         when(bytemanAttacher.attach(workingVmId, vmPid, agentId)).thenReturn(bytemanAgentInfo);
-        
+
         // mock that installing of helper jars works
         when(submit.addJarsToSystemClassLoader(any(List.class), any(BytemanAgentInfo.class))).thenReturn(true);
-        
+
         ProcessUserInfo info = new ProcessUserInfo(5000, "testUser");
         when(userInfoBuilder.build(vmPid)).thenReturn(info);
         UserPrincipal owner = mock(UserPrincipal.class);
         when(lookup.lookupPrincipalByName("testUser")).thenReturn(owner);
-        
+
         VmId vmId = new VmId(workingVmId);
         WriterID writerId = mock(WriterID.class);
         when(writerId.getWriterID()).thenReturn(agentId);
         manager.setWriterId(writerId);
         VmBytemanStatus bytemanStatus = manager.attachBytemanToVm(vmId, vmPid);
         VmSocketIdentifier socketId = new VmSocketIdentifier(workingVmId, vmPid, agentId);
-        
+
         // IPC endpoint must be started
         verify(ipcManager).startIPCEndpoint(eq(socketId), isA(BytemanMetricsReceiver.class), eq(owner));
-        
+
         // Status should have been updated/inserted
         ArgumentCaptor<VmBytemanStatus> statusCaptor = ArgumentCaptor.forClass(VmBytemanStatus.class);
-        verify(vmBytemanDao).addOrReplaceBytemanStatus(statusCaptor.capture());
+        verify(vmBytemanDao).addBytemanStatus(statusCaptor.capture());
         VmBytemanStatus capturedStatus = statusCaptor.getValue();
         assertNotNull(capturedStatus);
-        assertEquals(workingVmId, capturedStatus.getVmId());
+        assertEquals(workingVmId, capturedStatus.getJvmId());
         assertEquals(agentId, capturedStatus.getAgentId());
         assertEquals(listenPort, capturedStatus.getListenPort());
         assertNull(capturedStatus.getRule());
         assertTrue(capturedStatus.getTimeStamp() > 0);
-        
+
         // Helper jars must have been added to classpath
         verify(submit).addJarsToSystemClassLoader(eq((List)null), eq(bytemanAgentInfo));
-        
+
         assertEquals(listenPort, bytemanStatus.getListenPort());
     }
-    
+
     @SuppressWarnings("unchecked")
     @Test
     public void canUseOldAttachedAgentStartIPCandAddsStatus() throws IOException {
@@ -170,70 +170,70 @@
         int listenPort = 9881;
         BytemanAgentInfo bytemanAgentInfo = new BytemanAgentInfo(vmPid, listenPort, null, workingVmId, agentId, false, true);
         when(bytemanAttacher.attach(workingVmId, vmPid, agentId)).thenReturn(bytemanAgentInfo);
-        
+
         // mock setting system properties' success
         when(submit.setSystemProperties(any(Properties.class), any(BytemanAgentInfo.class))).thenReturn(true);
-        
+
         ProcessUserInfo info = new ProcessUserInfo(5000, "testUser");
         when(userInfoBuilder.build(vmPid)).thenReturn(info);
         UserPrincipal owner = mock(UserPrincipal.class);
         when(lookup.lookupPrincipalByName("testUser")).thenReturn(owner);
-        
+
         VmId vmId = new VmId(workingVmId);
         WriterID writerId = mock(WriterID.class);
         when(writerId.getWriterID()).thenReturn(agentId);
         manager.setWriterId(writerId);
         VmBytemanStatus bytemanStatus = manager.attachBytemanToVm(vmId, vmPid);
         VmSocketIdentifier socketId = new VmSocketIdentifier(workingVmId, vmPid, agentId);
-        
+
         // IPC endpoint must be started
         verify(ipcManager).startIPCEndpoint(eq(socketId), isA(BytemanMetricsReceiver.class), eq(owner));
-        
+
         // Status should have been updated/inserted
         ArgumentCaptor<VmBytemanStatus> statusCaptor = ArgumentCaptor.forClass(VmBytemanStatus.class);
-        verify(vmBytemanDao).addOrReplaceBytemanStatus(statusCaptor.capture());
+        verify(vmBytemanDao).addBytemanStatus(statusCaptor.capture());
         VmBytemanStatus capturedStatus = statusCaptor.getValue();
         assertNotNull(capturedStatus);
-        assertEquals(workingVmId, capturedStatus.getVmId());
+        assertEquals(workingVmId, capturedStatus.getJvmId());
         assertEquals(agentId, capturedStatus.getAgentId());
         assertEquals(listenPort, capturedStatus.getListenPort());
         assertNull(capturedStatus.getRule());
         assertTrue(capturedStatus.getTimeStamp() > 0);
-        
+
         // Helper jars must not have been added again to classpath
         verify(submit, times(0)).addJarsToSystemClassLoader(any(List.class), any(BytemanAgentInfo.class));
-        
+
         // Verify properties got set appropriately
         ArgumentCaptor<Properties> propsCaptor = ArgumentCaptor.forClass(Properties.class);
         verify(submit).setSystemProperties(propsCaptor.capture(), eq(bytemanAgentInfo));
         Properties props = propsCaptor.getValue();
         String propVal = props.getProperty(BytemanAgentAttachManager.THERMOSTAT_HELPER_SOCKET_NAME_PROPERTY);
         assertEquals(socketId.getName(), propVal);
-        
+
         assertEquals(listenPort, bytemanStatus.getListenPort());
     }
-    
+
     @Test
     public void usernameFailureDoesNotAttach() throws IOException {
         ProcessUserInfo info = new ProcessUserInfo(SOME_UID, null);
         when(userInfoBuilder.build(SOME_VM_PID)).thenReturn(info);
-        
+
         VmBytemanStatus status = manager.attachBytemanToVm(SOME_VM_ID, SOME_VM_PID);
         verify(bytemanAttacher, never()).attach(any(String.class), any(int.class), any(String.class));
         verify(ipcManager, never()).startIPCEndpoint(any(VmSocketIdentifier.class), any(ThermostatIPCCallbacks.class), any(UserPrincipal.class));
         assertNull(status);
     }
-    
+
     @Test
     public void userPrincipalExceptionDoesNotAttach() throws IOException {
         when(lookup.lookupPrincipalByName(SOME_USERNAME)).thenThrow(new IOException("TEST"));
-        
+
         VmBytemanStatus status = manager.attachBytemanToVm(SOME_VM_ID, SOME_VM_PID);
         verify(bytemanAttacher, never()).attach(any(String.class), any(int.class), any(String.class));
         verify(ipcManager, never()).startIPCEndpoint(any(VmSocketIdentifier.class), any(ThermostatIPCCallbacks.class), any(UserPrincipal.class));
         assertNull(status);
     }
-    
+
     @Test
     public void failureToAttachDoesNotStartIPC() throws Exception {
         BytemanAttacher failAttacher = getFailureAttacher();
@@ -248,21 +248,21 @@
         BytemanAttacher failAttacher = getFailureAttacher();
         manager.setAttacher(failAttacher);
         VmBytemanStatus status = manager.attachBytemanToVm(SOME_VM_ID, SOME_VM_PID);
-        verify(vmBytemanDao, never()).addOrReplaceBytemanStatus(any(VmBytemanStatus.class));
+        verify(vmBytemanDao, never()).addBytemanStatus(any(VmBytemanStatus.class));
         assertNull(status);
     }
-    
+
     @SuppressWarnings("unchecked")
     @Test
     public void successfulAttachAddsHelperJars() {
         // mock that installing of helper jars works
         when(submit.addJarsToSystemClassLoader(any(List.class), any(BytemanAgentInfo.class))).thenReturn(true);
-        
+
         when(bytemanAttacher.attach(SOME_VM_ID.get(), SOME_VM_PID, SOME_AGENT_ID)).thenReturn(SOME_SUCCESS_BYTEMAN_INFO);
         manager.attachBytemanToVm(SOME_VM_ID, SOME_VM_PID);
         verify(submit).addJarsToSystemClassLoader(any(List.class), any(BytemanAgentInfo.class));
     }
-    
+
     @Test
     public void canGetListOfJarsForBytemanHelper() {
         String parent = "/foo";
@@ -278,7 +278,7 @@
             assertEquals("/foo/test-file" + i + ".jar", jars.get(i));
         }
     }
-    
+
     @SuppressWarnings("unchecked")
     private BytemanAttacher getFailureAttacher() throws Exception {
         AgentIPCService ipcService = mock(AgentIPCService.class);
--- a/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiverTest.java	Mon Sep 18 14:04:16 2017 +0200
+++ b/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanMetricsReceiverTest.java	Fri Sep 22 10:10:52 2017 -0400
@@ -53,9 +53,9 @@
 import org.mockito.ArgumentCaptor;
 
 import com.redhat.thermostat.agent.ipc.server.IPCMessage;
-import com.redhat.thermostat.vm.byteman.common.BytemanMetric;
-import com.redhat.thermostat.vm.byteman.common.JsonHelper;
-import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO;
+import com.redhat.thermostat.vm.byteman.agent.BytemanMetric;
+import com.redhat.thermostat.vm.byteman.agent.VmBytemanDAO;
+import com.redhat.thermostat.vm.byteman.agent.internal.typeadapter.JsonHelper;
 
 public class BytemanMetricsReceiverTest {
 
@@ -74,7 +74,7 @@
         receiver.messageReceived(message);
         verify(dao, times(3)).addMetric(metricsCaptor.capture());
         List<BytemanMetric> metrics = metricsCaptor.getAllValues();
-        assertEquals("vm-id", metrics.get(0).getVmId());
+        assertEquals("vm-id", metrics.get(0).getJvmId());
         assertEquals("agent-id", metrics.get(2).getAgentId());
         assertTrue(metrics.get(1).getTimeStamp() > 0);
         assertEquals("baz0", metrics.get(0).getMarker());
--- a/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiverTest.java	Mon Sep 18 14:04:16 2017 +0200
+++ b/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiverTest.java	Fri Sep 22 10:10:52 2017 -0400
@@ -46,10 +46,11 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import java.net.InetSocketAddress;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.SortedMap;
+import java.util.TreeMap;
 
 import org.jboss.byteman.agent.submit.ScriptText;
 import org.jboss.byteman.agent.submit.Submit;
@@ -58,40 +59,40 @@
 import org.mockito.ArgumentCaptor;
 
 import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
-import com.redhat.thermostat.common.command.Request;
-import com.redhat.thermostat.common.command.Request.RequestType;
-import com.redhat.thermostat.common.command.Response;
-import com.redhat.thermostat.common.command.Response.ResponseType;
+import com.redhat.thermostat.commands.model.AgentRequest;
+import com.redhat.thermostat.commands.model.WebSocketResponse;
+import com.redhat.thermostat.commands.model.WebSocketResponse.ResponseType;
+import com.redhat.thermostat.jvm.overview.agent.model.VmId;
 import com.redhat.thermostat.shared.config.CommonPaths;
-import com.redhat.thermostat.storage.core.VmId;
 import com.redhat.thermostat.storage.core.WriterID;
-import com.redhat.thermostat.storage.model.VmInfo;
-import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO;
-import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus;
-import com.redhat.thermostat.vm.byteman.common.command.BytemanRequest;
-import com.redhat.thermostat.vm.byteman.common.command.BytemanRequest.RequestAction;
+import com.redhat.thermostat.vm.byteman.agent.VmBytemanDAO;
+import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus;
+import com.redhat.thermostat.vm.byteman.agent.internal.BytemanRequest.RequestAction;
 
 public class BytemanRequestReceiverTest {
-    
+
+    private static final String SYSTEM_ID = "some-system-id";
     private static final String SOME_VM_ID = "some-vm-id";
     private static final int SOME_LISTENPORT_BTM_AGENT_ATTACHED = 333;
     private static final String SOME_WRITER_ID = "some-writer-id";
     private static final String SOME_RULE = "some-rule";
-    private VmInfo someVmInfo;
-    
+    private static final String BYTEMAN_ACTION = "byteman";
+    private static final int UNSET_JVM_PID = -99;
+    private static final String NO_RULE = null;
+    private long sequence;
+
     @Before
     public void setup() {
-        someVmInfo = mock(VmInfo.class);
-        when(someVmInfo.getVmId()).thenReturn(SOME_VM_ID);
+        sequence = (long)(1000 * Math.random());
     }
-    
+
     @Test
     public void testLoadRulesAgentAttached() throws Exception {
         Submit submit = mock(Submit.class);
         doBasicLoadRulesTestBtmAgentAttached(submit);
         verify(submit, never()).deleteAllRules();
     }
-    
+
     @Test
     public void testLoadRulesAgentAttachedWithRulesExisting() throws Exception {
         Submit submit = mock(Submit.class);
@@ -99,17 +100,29 @@
         doBasicLoadRulesTestBtmAgentAttached(submit);
         verify(submit).deleteAllRules();
     }
-    
+
     @Test
     public void testUnLoadRulesWithNoExistingRules() throws Exception {
         Submit submit = mock(Submit.class);
         when(submit.getAllScripts()).thenReturn(Collections.<ScriptText>emptyList());
         BytemanRequestReceiver receiver = createReceiver(submit, null, null);
-        Response response = receiver.receive(BytemanRequest.create(mock(InetSocketAddress.class), someVmInfo, RequestAction.UNLOAD_RULES, -1));
-        assertEquals(ResponseType.OK, response.getType());
+        int someListenPort = 29320;
+        int someJvmPid = 3280;
+        WebSocketResponse response = receiver.receive(createRequest(RequestAction.UNLOAD_RULES, someListenPort, NO_RULE, someJvmPid));
+        assertEquals(ResponseType.OK, response.getResponseType());
+        assertEquals(sequence, response.getSequenceId());
         verify(submit, never()).deleteAllRules();
     }
-    
+
+    @Test
+    public void testReceiveBadAction() throws Exception {
+        AgentRequest request = new AgentRequest(sequence, "wrong-action", SYSTEM_ID, SOME_VM_ID, new TreeMap<String, String>());
+        BytemanRequestReceiver receiver = createReceiver(mock(Submit.class), mock(WriterID.class), mock(VmBytemanDAO.class));
+        WebSocketResponse response = receiver.receive(request);
+        assertEquals(ResponseType.ERROR, response.getResponseType());
+        assertEquals(sequence, response.getSequenceId());
+    }
+
     @Test
     public void testUnLoadRulesWithExistingRules() throws Exception {
         Submit submit = mock(Submit.class);
@@ -118,30 +131,34 @@
         String someAgentId = "some-agent-id";
         String someVmId = "some-vm-id";
         int someListenPort = 3333;
+        int someJvmPid = 2321;
         VmBytemanDAO bytemanDao = mock(VmBytemanDAO.class);
         when(writerId.getWriterID()).thenReturn(someAgentId);
         BytemanRequestReceiver receiver = createReceiver(submit, writerId, bytemanDao);
         ArgumentCaptor<VmBytemanStatus> statusCaptor = ArgumentCaptor.forClass(VmBytemanStatus.class);
-        Response response = receiver.receive(BytemanRequest.create(mock(InetSocketAddress.class), someVmInfo, RequestAction.UNLOAD_RULES, someListenPort));
-        assertEquals(ResponseType.OK, response.getType());
+        WebSocketResponse response = receiver.receive(createRequest(RequestAction.UNLOAD_RULES, someListenPort, NO_RULE, someJvmPid));
+        assertEquals(ResponseType.OK, response.getResponseType());
+        assertEquals(sequence, response.getSequenceId());
         verify(submit).deleteAllRules();
-        verify(bytemanDao).addOrReplaceBytemanStatus(statusCaptor.capture());
+        verify(bytemanDao).addBytemanStatus(statusCaptor.capture());
         VmBytemanStatus status = statusCaptor.getValue();
         assertEquals(someAgentId, status.getAgentId());
-        assertEquals(someVmId, status.getVmId());
+        assertEquals(someVmId, status.getJvmId());
         assertEquals(someListenPort, status.getListenPort());
         assertNull(status.getRule());
     }
-    
+
     @Test
     public void testReceiveWithBadAction() {
-        Request badRequest = new Request(RequestType.RESPONSE_EXPECTED, mock(InetSocketAddress.class));
-        badRequest.setParameter(BytemanRequest.ACTION_PARAM_NAME, Integer.toString(-1));
+        SortedMap<String, String> paramMap = new TreeMap<>();
+        paramMap.put(BytemanRequest.ACTION_PARAM_NAME, Integer.toString(-1));
+        AgentRequest badRequest = new AgentRequest(sequence, "byteman", "some-system-id", "jvm-id-foo", paramMap);
         BytemanRequestReceiver receiver = new BytemanRequestReceiver();
-        Response response = receiver.receive(badRequest);
-        assertEquals(ResponseType.ERROR, response.getType());
+        WebSocketResponse response = receiver.receive(badRequest);
+        assertEquals(ResponseType.ERROR, response.getResponseType());
+        assertEquals(sequence, response.getSequenceId());
     }
-    
+
     @SuppressWarnings("unchecked")
     @Test
     public void testLoadRuleWithBytemanAgentNotAttached() throws Exception {
@@ -155,7 +172,7 @@
         WriterID wid = mock(WriterID.class);
         when(wid.getWriterID()).thenReturn(SOME_WRITER_ID);
         BytemanRequestReceiver receiver = new BytemanRequestReceiver(attachManager) {
-            @Override 
+            @Override
             protected Submit getSubmit(int port) {
                 assertEquals(listenPort, port);
                 return submit;
@@ -163,36 +180,35 @@
         };
         receiver.bindWriterId(wid);
         receiver.bindVmBytemanDao(bytemanDao);
-        VmInfo vmInfo = mock(VmInfo.class);
-        when(vmInfo.getVmId()).thenReturn(SOME_VM_ID);
         int someVmPid = 3023;
-        when(vmInfo.getVmPid()).thenReturn(someVmPid);
-        Request loadRequest = BytemanRequest.create(mock(InetSocketAddress.class), vmInfo, RequestAction.LOAD_RULES, BytemanRequest.NOT_ATTACHED_PORT, SOME_RULE);
+        AgentRequest loadRequest = createRequest(RequestAction.LOAD_RULES, BytemanRequest.NOT_ATTACHED_PORT, SOME_RULE, someVmPid);
         receiver.receive(loadRequest);
         VmId vmId = new VmId(SOME_VM_ID);
         verify(attachManager).attachBytemanToVm(eq(vmId), eq(someVmPid));
         verify(submit).addRulesFromResources(any(List.class));
     }
-    
+
     @Test
     public void testUnloadRuleIllegalPid() {
-        VmInfo vmInfoWithBadPid = mock(VmInfo.class);
-        when(vmInfoWithBadPid.getVmPid()).thenReturn(-1); // bad value
-        Request loadRequest = BytemanRequest.create(mock(InetSocketAddress.class), vmInfoWithBadPid, RequestAction.UNLOAD_RULES, SOME_LISTENPORT_BTM_AGENT_ATTACHED);
+        int badJvmPid = -1;
+        AgentRequest loadRequest = createRequest(RequestAction.UNLOAD_RULES, SOME_LISTENPORT_BTM_AGENT_ATTACHED, NO_RULE, badJvmPid);
         BytemanRequestReceiver receiver = new BytemanRequestReceiver();
-        Response response = receiver.receive(loadRequest);
-        assertEquals(ResponseType.ERROR, response.getType());
+        WebSocketResponse response = receiver.receive(loadRequest);
+        assertEquals(ResponseType.ERROR, response.getResponseType());
+        assertEquals(sequence, response.getSequenceId());
     }
-    
+
     @Test
     public void testUnloadRuleIllegalPort() {
         int invalidPort = -3;
-        Request loadRequest = BytemanRequest.create(mock(InetSocketAddress.class), someVmInfo, RequestAction.UNLOAD_RULES, invalidPort);
+        int validPid = 2302;
+        AgentRequest loadRequest = createRequest(RequestAction.UNLOAD_RULES, invalidPort, NO_RULE, validPid);
         BytemanRequestReceiver receiver = new BytemanRequestReceiver();
-        Response response = receiver.receive(loadRequest);
-        assertEquals(ResponseType.ERROR, response.getType());
+        WebSocketResponse response = receiver.receive(loadRequest);
+        assertEquals(ResponseType.ERROR, response.getResponseType());
+        assertEquals(sequence, response.getSequenceId());
     }
-    
+
     @Test
     public void testBindWriterId() {
         BytemanAgentAttachManager attachManager = mock(BytemanAgentAttachManager.class);
@@ -201,7 +217,7 @@
         receiver.bindWriterId(wid);
         verify(attachManager).setWriterId(wid);
     }
-    
+
     @Test
     public void testBindVmBytemanDAO() {
         BytemanAgentAttachManager attachManager = mock(BytemanAgentAttachManager.class);
@@ -210,7 +226,7 @@
         receiver.bindVmBytemanDao(dao);
         verify(attachManager).setVmBytemanDao(dao);
     }
-    
+
     @Test
     public void testBindCommonPaths() {
         BytemanAgentAttachManager attachManager = mock(BytemanAgentAttachManager.class);
@@ -219,7 +235,7 @@
         receiver.bindCommonPaths(paths);
         verify(attachManager).setPaths(paths);
     }
-    
+
     @Test
     public void testBindAgentIPCService() {
         BytemanAgentAttachManager attachManager = mock(BytemanAgentAttachManager.class);
@@ -232,35 +248,51 @@
 
     @SuppressWarnings("unchecked")
     private void doBasicLoadRulesTestBtmAgentAttached(Submit submit) throws Exception {
+        int someValidPid = 3090;
         VmBytemanDAO bytemanDao = mock(VmBytemanDAO.class);
         WriterID wid = mock(WriterID.class);
         when(wid.getWriterID()).thenReturn(SOME_WRITER_ID);
         BytemanRequestReceiver receiver = createReceiver(submit, wid, bytemanDao);
         ArgumentCaptor<VmBytemanStatus> statusCaptor = ArgumentCaptor.forClass(VmBytemanStatus.class);
-        Response response = receiver.receive(BytemanRequest.create(mock(InetSocketAddress.class), someVmInfo, RequestAction.LOAD_RULES, SOME_LISTENPORT_BTM_AGENT_ATTACHED, SOME_RULE));
-        verify(bytemanDao).addOrReplaceBytemanStatus(statusCaptor.capture());
+        WebSocketResponse response = receiver.receive(createRequest(RequestAction.LOAD_RULES, SOME_LISTENPORT_BTM_AGENT_ATTACHED, SOME_RULE, someValidPid));
+        verify(bytemanDao).addBytemanStatus(statusCaptor.capture());
         VmBytemanStatus capturedStatus = statusCaptor.getValue();
-        assertEquals(SOME_VM_ID, capturedStatus.getVmId());
+        assertEquals(SOME_VM_ID, capturedStatus.getJvmId());
         assertEquals(SOME_WRITER_ID, capturedStatus.getAgentId());
         assertEquals(SOME_RULE, capturedStatus.getRule());
         assertEquals(SOME_LISTENPORT_BTM_AGENT_ATTACHED, capturedStatus.getListenPort());
         // verify no helper jars get added on rule submission
         verify(submit, times(0)).addJarsToSystemClassloader(any(List.class));
         verify(submit).addRulesFromResources(any(List.class));
-        assertEquals(ResponseType.OK, response.getType());
+        assertEquals(ResponseType.OK, response.getResponseType());
+        assertEquals(sequence, response.getSequenceId());
     }
 
     private BytemanRequestReceiver createReceiver(final Submit submit, WriterID writerId, VmBytemanDAO dao) {
         BytemanRequestReceiver receiver = new BytemanRequestReceiver() {
-            @Override 
+            @Override
             protected Submit getSubmit(int port) {
                 return submit;
             }
-            
+
         };
         receiver.bindVmBytemanDao(dao);
         receiver.bindWriterId(writerId);
         return receiver;
     }
-    
+
+    private AgentRequest createRequest(RequestAction action, int listenPort, String someRule, int jvmPid) {
+        SortedMap<String, String> params = new TreeMap<>();
+        params.put(BytemanRequest.ACTION_PARAM_NAME, Integer.toString(action.getActionId()));
+        params.put(BytemanRequest.LISTEN_PORT_PARAM_NAME, Integer.toString(listenPort));
+        if (someRule != null) {
+            params.put(BytemanRequest.RULE_PARAM_NAME, someRule);
+        }
+        if (jvmPid != UNSET_JVM_PID) {
+            params.put(BytemanRequest.VM_PID_PARAM_NAME, Integer.toString(jvmPid));
+        }
+        AgentRequest request = new AgentRequest(sequence, BYTEMAN_ACTION, SYSTEM_ID, SOME_VM_ID, params);
+        return request;
+    }
+
 }
--- a/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/IPCEndpointsManagerTest.java	Mon Sep 18 14:04:16 2017 +0200
+++ b/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/IPCEndpointsManagerTest.java	Fri Sep 22 10:10:52 2017 -0400
@@ -52,7 +52,7 @@
 
 import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
 import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks;
-import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO;
+import com.redhat.thermostat.vm.byteman.agent.VmBytemanDAO;
 
 public class IPCEndpointsManagerTest {
     
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapter/BytemanMetricTypeAdapterTest.java	Fri Sep 22 10:10:52 2017 -0400
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2012-2017 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.byteman.agent.internal.typeadapter;
+
+import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.redhat.thermostat.vm.byteman.agent.BytemanMetric;
+import com.redhat.thermostat.vm.byteman.agent.internal.typeadapters.BytemanTypeAdapterFactory;
+
+public class BytemanMetricTypeAdapterTest {
+    
+    private static final double DELTA = 0.001;
+    
+    private Gson gson;
+    
+    @Before
+    public void setup() {
+        gson = new GsonBuilder()
+                .registerTypeAdapterFactory(new BytemanTypeAdapterFactory())
+                .disableHtmlEscaping()
+                .serializeNulls()
+                .create();
+    }
+
+    @Test
+    public void canDeserializeArrayOfMetrics() {
+        String json = JsonHelper.buildJsonArray(10);
+        BytemanMetric[] metrics = gson.fromJson(json, BytemanMetric[].class);
+        assertEquals(10, metrics.length);
+        for (int i = 0; i < 10; i++) {
+            assertEquals("baz" + i, metrics[i].getMarker());
+            assertEquals(1234567890 + i, metrics[i].getTimeStamp());
+            Map<String, Object> dataAsMap = metrics[i].getDataAsMap();
+            assertFalse((Boolean)dataAsMap.get("foo4"));
+            assertEquals("[]", (String)dataAsMap.get("foo5"));
+            double foo3Val = (double)dataAsMap.get("foo3");
+            String foo3Str = String.format("42.%d", i);
+            double expectedFoo3Val = Double.parseDouble(foo3Str); 
+            assertEquals(expectedFoo3Val, foo3Val, DELTA);
+            double foo2Val = (double)dataAsMap.get("foo2");
+            String foo2Str = String.format("42%d.0", i);
+            double expectedFoo2Val = Double.parseDouble(foo2Str);
+            assertEquals(expectedFoo2Val, foo2Val, DELTA);
+            assertEquals("ba\"r1", (String)dataAsMap.get("foo1"));
+            assertEquals("Expected 7 key value pairs", 7, dataAsMap.keySet().size());
+            assertTrue(dataAsMap.containsKey("key"));
+            assertNull("value for \"key\" is null", dataAsMap.get("key"));
+            Double rawLong = (Double)dataAsMap.get("long");
+            long longVal = rawLong.longValue();
+            assertEquals(10_000_000_001L, longVal);
+        }
+    }
+    
+    /*
+     * This is a test which makes sure that html characters don't get
+     * escaped. We were seeing instances where the following happened which this
+     * test is trying to catch:
+     * 
+     * before JSON deserialization: {"key": "value = 'foo', 'bar', 'baz'"}
+     * after JSON deserialization: {"key"; "value \u003d \u0027foo\u0027, \u0027bar\u0027, \u0027baz\u0027"}
+     */
+    @Test
+    public void canDeserializeMetricWithSpecialChar() {
+        String json = "{\n" +
+                "    \"marker\": \"marker\",\n" +
+                "    \"timestamp\":\"30\",\n" +
+                "    \"data\": {\n" +
+                "        \"key\": \"value = 'foo', 'bar', 'baz'\"\n" +
+                "    }\n" +
+                "}";
+        BytemanMetric metric = gson.fromJson(json, BytemanMetric.class);
+        assertJsonEquals("{\"key\":\"value = 'foo', 'bar', 'baz'\"}", metric.getData());
+        Map<String, Object> dataAsMap = metric.getDataAsMap();
+        assertEquals("value = 'foo', 'bar', 'baz'", dataAsMap.get("key"));
+    }
+
+    @Test
+    public void testWrite() {
+        BytemanMetric metric = new BytemanMetric();
+        metric.setTimeStamp(100l);
+        metric.setJvmId("Vm-1");
+        metric.setAgentId("Agent-1");
+        metric.setMarker("Marker");
+        metric.setData("{\"data\":\"This is data\"}");
+        assertJsonEquals("{\"agentId\":\"Agent-1\",\"jvmId\":\"Vm-1\",\"marker\":\"Marker\",\"payload\":\"{\\\"data\\\":\\\"This is data\\\"}\",\"timeStamp\":{\"$numberLong\":\"100\"}}", gson.toJson(metric));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapter/JsonHelper.java	Fri Sep 22 10:10:52 2017 -0400
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2012-2017 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.byteman.agent.internal.typeadapter;
+
+public class JsonHelper {
+
+    public static String buildJsonArray(int length) {
+        String elemFormat = 
+        "{\n" +
+                "    \"marker\": \"baz%d\",\n" +
+                "    \"timestamp\":\"%d\",\n" +
+                "    \"data\": {\n" +
+                "        \"foo1\": \"ba\\\"r1\",\n" +
+                "        \"foo2\": 42%d,\n" +
+                "        \"foo3\": 42.%d,\n" +
+                "        \"foo4\": false,\n" +
+                "        \"foo5\": \"[]\",\n" +
+                "        \"key\": null,\n" +
+                "        \"long\": 10000000001\n" +
+                "    }\n" +
+                "}";
+        StringBuilder builder = new StringBuilder();
+        builder.append("[");
+        for (int i = 0; i < length; i++) {
+            builder.append(String.format(elemFormat, i, 1234567890 + i, i, i));
+            builder.append(",");
+        }
+        if (length > 0) {
+            builder.deleteCharAt(builder.length() - 1);
+        }
+        builder.append("]");
+        return builder.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/typeadapter/VmBytemanStatusTypeAdapterTest.java	Fri Sep 22 10:10:52 2017 -0400
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2012-2017 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.byteman.agent.internal.typeadapter;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.redhat.thermostat.vm.byteman.agent.VmBytemanStatus;
+import com.redhat.thermostat.vm.byteman.agent.internal.typeadapters.VmBytemanStatusTypeAdapter;
+
+import org.junit.Test;
+
+import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals;
+
+public class VmBytemanStatusTypeAdapterTest {
+
+    @Test
+    public void testWrite() {
+        GsonBuilder builder = new GsonBuilder();
+        builder.registerTypeAdapter(VmBytemanStatus.class, new VmBytemanStatusTypeAdapter());
+        Gson gson = builder.create();
+        VmBytemanStatus status = new VmBytemanStatus();
+        status.setTimeStamp(100l);
+        status.setAgentId("Agent-1");
+        status.setJvmId("Vm-1");
+        status.setListenPort(27518);
+        status.setRule("Rule");
+        assertJsonEquals("{\"agentId\":\"Agent-1\",\"jvmId\":\"Vm-1\",\"timeStamp\":{\"$numberLong\":\"100\"},\"rule\":\"Rule\",\"listenPort\":27518}", gson.toJson(status));
+    }
+
+}
--- a/plugins/vm-byteman/common/pom.xml	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- Copyright 2012-2017 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-byteman</artifactId>
-    <groupId>com.redhat.thermostat</groupId>
-    <version>1.99.12-SNAPSHOT</version>
-  </parent>
-  <artifactId>thermostat-vm-byteman-common</artifactId>
-  <packaging>bundle</packaging>
-  <name>Thermostat VM Byteman Common 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.byteman.common</Bundle-SymbolicName>
-            <Export-Package>
-              com.redhat.thermostat.vm.byteman.common,
-              com.redhat.thermostat.vm.byteman.common.command,
-            </Export-Package>
-            <Private-Package>
-              com.redhat.thermostat.vm.byteman.common.internal
-            </Private-Package>
-            <!-- Do not autogenerate uses clauses in Manifests -->
-            <_nouses>true</_nouses>
-          </instructions>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-scr-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>generate-scr-scrdescriptor</id>
-            <goals>
-              <goal>scr</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <!-- generate a test-jar since the vm-byteman-agent tests need
-           JsonHelper which is in the test-jar only -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>test-jar</goal>
-            </goals>
-          </execution>
-        </executions>
-      </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-common-command</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>
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-storage-testutils</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-    </dependency>
-    <!-- declarative services -->
-    <dependency>
-      <groupId>org.apache.felix</groupId>
-      <artifactId>org.apache.felix.scr.annotations</artifactId>
-    </dependency>
-  </dependencies>
-</project>
--- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/BytemanMetric.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonSyntaxException;
-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 BytemanMetric extends BasePojo implements TimeStampedPojo {
-
-    private static final Gson GSON = new GsonBuilder().serializeNulls().create();
-    public static final String MARKER_NAME = "marker";
-    public static final String TIMESTAMP_NAME = "timestamp";
-    public static final String DATA_NAME = "data";
-    private String vmId;
-    private String marker;
-    private String jsonPayload;
-    private long timestamp;
-    
-    public BytemanMetric(String writerId) {
-        super(writerId);
-    }
-    
-    public BytemanMetric() {
-        this(null);
-    }
-    
-    @Persist
-    public String getVmId() {
-        return vmId;
-    }
-
-    @Persist
-    public void setVmId(String vmId) {
-        this.vmId = vmId;
-    }
-
-    /**
-     * Get the marker for this Byteman metric. A marker can be thought of a
-     * category for related metrics.
-     * 
-     * @return The marker for this metric.
-     */
-    @Persist
-    public String getMarker() {
-        return marker;
-    }
-
-    @Persist
-    public void setMarker(String marker) {
-        this.marker = marker;
-    }
-
-    @Persist
-    public void setTimeStamp(long timestamp) {
-        this.timestamp = timestamp;
-    }
-
-    @Persist
-    @Override
-    public long getTimeStamp() {
-        return timestamp;
-    }
-    
-    @Persist
-    public void setData(String json) {
-        this.jsonPayload = json;
-    }
-    
-    @Persist
-    public String getData() {
-        return jsonPayload;
-    }
-    
-    /**
-     * Get the metrics payload as raw JSON string. The payload is a JSON object
-     * in key, value form. Supported value types are {@code Boolean},
-     * {@code String} and {@code Double}.
-     * 
-     * @return The raw JSON string.
-     */
-    public String getDataAsJson() {
-        return getData();
-    }
-    
-    /**
-     * Get the metrics payload as parsed {@link Map}. Supported value types are
-     * {@code Boolean}, {@code String} and {@code Double}.
-     * 
-     * @return The parsed JSON payload as {@link Map}.
-     */
-    @SuppressWarnings("unchecked")
-    public Map<String, Object> getDataAsMap() {
-        try {
-            return (Map<String, Object>)GSON.fromJson(jsonPayload, HashMap.class);
-        } catch (JsonSyntaxException e) {
-            throw new RuntimeException("Payload not in expected format. Payload was: " + jsonPayload);
-        }
-    }
-
-}
--- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/BytemanMetricDataExtractor.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-
-public class BytemanMetricDataExtractor {
-    
-    private final Set<String> keySet;
-
-    public BytemanMetricDataExtractor() {
-        this.keySet = new HashSet<>();
-    }
-    
-    public void mineMetric(BytemanMetric m) {
-        Objects.requireNonNull(m);
-        Map<String, Object> dataMap = m.getDataAsMap();
-        if (dataMap != null) {
-            for (String key: dataMap.keySet()) {
-                keySet.add(key);
-            }
-        }
-    }
-    
-    /**
-     * 
-     * @return A sorted list of the set of keys.
-     */
-    public List<String> getSortedKeySet() {
-        List<String> returnedList = new ArrayList<>(keySet);
-        Collections.sort(returnedList);
-        return returnedList;
-    }
-
-}
--- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/BytemanMetricTypeAdapterFactory.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common;
-
-import com.google.gson.Gson;
-import com.google.gson.TypeAdapter;
-import com.google.gson.TypeAdapterFactory;
-import com.google.gson.reflect.TypeToken;
-import com.redhat.thermostat.vm.byteman.common.internal.BytemanMetricTypeAdapter;
-
-public class BytemanMetricTypeAdapterFactory implements TypeAdapterFactory {
-
-    @Override
-    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
-        Class<?> rawType = type.getRawType();
-        if (rawType == BytemanMetric.class) {
-            @SuppressWarnings("unchecked")
-            TypeAdapter<T> ta = (TypeAdapter<T>)new BytemanMetricTypeAdapter(gson);
-            return ta;
-        }
-        return null;
-    }
-
-}
--- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/VmBytemanDAO.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common;
-
-import java.util.List;
-
-import com.redhat.thermostat.common.model.Range;
-import com.redhat.thermostat.storage.core.AgentId;
-import com.redhat.thermostat.storage.core.VmId;
-
-public interface VmBytemanDAO {
-
-    void addMetric(BytemanMetric metric);
-    
-    void addOrReplaceBytemanStatus(VmBytemanStatus status);
-    
-    VmBytemanStatus findBytemanStatus(VmId vmId);
-    
-    List<BytemanMetric> findBytemanMetrics(Range<Long> timeRange, VmId vmId, AgentId agentId);
-}
--- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/VmBytemanStatus.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.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 VmBytemanStatus extends BasePojo implements TimeStampedPojo {
-
-    private String vmId;
-    private long timestamp;
-    private String rule;
-    private int listenPort;
-    
-    public VmBytemanStatus(String writerId) {
-        super(writerId);
-    }
-    
-    public VmBytemanStatus() {
-        super(null);
-    }
-    
-    @Persist
-    public String getVmId() {
-        return vmId;
-    }
-
-    @Persist
-    public void setVmId(String vmId) {
-        this.vmId = vmId;
-    }
-    
-    @Persist
-    public void setTimeStamp(long timestamp) {
-        this.timestamp = timestamp;
-    }
-
-    @Persist
-    @Override
-    public long getTimeStamp() {
-        return timestamp;
-    }
-    
-    @Persist
-    public void setRule(String rule) {
-        this.rule = rule;
-    }
-    
-    @Persist
-    public String getRule() {
-        return rule;
-    }
-    
-    @Persist
-    public void setListenPort(int port) {
-        this.listenPort = port;
-    }
-    
-    @Persist
-    public int getListenPort() {
-        return listenPort;
-    }
-
-}
--- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/command/BytemanRequest.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common.command;
-
-import java.net.InetSocketAddress;
-
-import com.redhat.thermostat.common.command.Request;
-import com.redhat.thermostat.common.command.Request.RequestType;
-import com.redhat.thermostat.storage.model.VmInfo;
-
-public class BytemanRequest {
-    
-    public static enum RequestAction {
-        LOAD_RULES(0),
-        UNLOAD_RULES(1),
-        ;
-        
-        private int actionId;
-        private RequestAction(int id) {
-            this.actionId = id;
-        }
-        
-        public static RequestAction fromIntString(String id) {
-            int intId;
-            try {
-                intId = Integer.parseInt(id);
-            } catch (NumberFormatException e) {
-                throw new IllegalArgumentException("Unknown action: " + id);
-            }
-            switch(intId) {
-            case(0): return LOAD_RULES;
-            case(1): return UNLOAD_RULES;
-            default:
-                throw new IllegalArgumentException("Unknown action: " + id);
-            }
-        }
-        
-        private String toIntString() {
-            return Integer.toString(actionId);
-        }
-    }
-    
-    private static final String CMD_CHANN_ACTION_NAME = "vm-byteman-instrument";
-    private static final String RECEIVER = "com.redhat.thermostat.vm.byteman.agent.internal.BytemanRequestReceiver";
-    
-    public static final String VM_ID_PARAM_NAME = "vm-id";
-    public static final String VM_PID_PARAM_NAME = "vm-pid";
-    public static final String ACTION_PARAM_NAME = "byteman-action";
-    public static final String LISTEN_PORT_PARAM_NAME = "listen-port";
-    public static final String RULE_PARAM_NAME = "byteman-rule";
-    public static final int NOT_ATTACHED_PORT = -1;
-
-    public static Request create(InetSocketAddress address, VmInfo vmInfo, RequestAction action, int listenPort) {
-        Request req = new Request(RequestType.RESPONSE_EXPECTED, address);
-        req.setReceiver(RECEIVER);
-        req.setParameter(Request.ACTION, CMD_CHANN_ACTION_NAME);
-        req.setParameter(VM_ID_PARAM_NAME, vmInfo.getVmId());
-        req.setParameter(VM_PID_PARAM_NAME, Integer.toString(vmInfo.getVmPid()));
-        req.setParameter(ACTION_PARAM_NAME, action.toIntString());
-        req.setParameter(LISTEN_PORT_PARAM_NAME, Integer.toString(listenPort));
-        return req;
-    }
-    
-    public static Request create(InetSocketAddress address, VmInfo vmInfo, RequestAction action, int listenPort, String rule) {
-        Request req = create(address, vmInfo, action, listenPort);
-        req.setParameter(RULE_PARAM_NAME, rule);
-        return req;
-    }
-    
-}
--- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/command/BytemanRequestResponseListener.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common.command;
-
-import java.util.concurrent.CountDownLatch;
-
-import com.redhat.thermostat.common.command.Request;
-import com.redhat.thermostat.common.command.RequestResponseListener;
-import com.redhat.thermostat.common.command.Response;
-import com.redhat.thermostat.shared.locale.Translate;
-import com.redhat.thermostat.vm.byteman.common.internal.LocaleResources;
-
-public class BytemanRequestResponseListener implements RequestResponseListener {
-    
-    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
-    private final CountDownLatch latch;
-    private String errorMsg = "";
-    private boolean isError = false;
-    
-    public BytemanRequestResponseListener(CountDownLatch latch) {
-        this.latch = latch;
-    }
-
-    @Override
-    public void fireComplete(Request request, Response response) {
-        switch(response.getType()) {
-        case AUTH_FAILED:
-            isError = true;
-            errorMsg = t.localize(LocaleResources.REQUEST_FAILED_AUTH_ISSUE).getContents();
-            break;
-        case ERROR:
-            isError = true;
-            errorMsg = t.localize(LocaleResources.REQUEST_FAILED_UNKNOWN_ISSUE).getContents();
-            break;
-        case OK:
-            break;
-        default:
-            isError = true;
-            errorMsg = t.localize(LocaleResources.ERROR_UNKNOWN_RESPONSE, response.getType().toString()).getContents();
-        }
-        latch.countDown();
-    }
-    
-    public String getErrorMessage() {
-        return errorMsg;
-    }
-    
-    public boolean isError() {
-        return isError;
-    }
-
-}
--- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricTypeAdapter.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common.internal;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.google.gson.Gson;
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonToken;
-import com.google.gson.stream.JsonWriter;
-import com.redhat.thermostat.vm.byteman.common.BytemanMetric;
-
-public class BytemanMetricTypeAdapter extends TypeAdapter<BytemanMetric> {
-    
-    private final Gson gson;
-    
-    public BytemanMetricTypeAdapter(Gson gson) {
-        this.gson = gson;
-    }
-
-    @Override
-    public BytemanMetric read(JsonReader reader) throws IOException {
-        // handle null
-        if (reader.peek() == JsonToken.NULL) {
-            reader.nextNull();
-            return null;
-        }
-        
-        reader.beginObject();
-        BytemanMetric metric = parseMetric(reader);
-        reader.endObject();
-        return metric;
-    }
-
-    @Override
-    public void write(JsonWriter writer, BytemanMetric metric) throws IOException {
-        throw new RuntimeException("Not implemented");
-    }
-    
-    @SuppressWarnings("unchecked")
-    private BytemanMetric parseMetric(JsonReader reader) throws IOException {
-        Map<String, Object> values = new HashMap<>();
-        while (reader.hasNext()) {
-            String name = reader.nextName();
-            switch(name) {
-                case BytemanMetric.MARKER_NAME:
-                    values.put(BytemanMetric.MARKER_NAME, reader.nextString());
-                    break;
-                case BytemanMetric.TIMESTAMP_NAME:
-                    values.put(BytemanMetric.TIMESTAMP_NAME, Long.valueOf(reader.nextString()));
-                    break;
-            case BytemanMetric.DATA_NAME:
-                Map<String, Object> data = getDataValues(reader);
-                values.put(BytemanMetric.DATA_NAME, data);
-                break;
-            default:
-                throw new IllegalStateException("Unknown name: '" + name + "'");
-            }
-        }
-        BytemanMetric metric = new BytemanMetric();
-        metric.setMarker((String)values.get(BytemanMetric.MARKER_NAME));
-        metric.setTimeStamp((Long)values.get(BytemanMetric.TIMESTAMP_NAME));
-        metric.setData(mapToJson((Map<String, Object>)values.get(BytemanMetric.DATA_NAME)));
-        return metric;
-    }
-
-    private String mapToJson(Map<String, Object> map) {
-        return gson.toJson(map, HashMap.class);
-    }
-
-    private Map<String, Object> getDataValues(JsonReader reader) throws IOException {
-        return gson.fromJson(reader, HashMap.class);
-    }
-
-}
--- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricWebTypeAdapter.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common.internal;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import com.redhat.thermostat.vm.byteman.common.BytemanMetric;
-
-import java.io.IOException;
-
-public class BytemanMetricWebTypeAdapter extends TypeAdapter<BytemanMetric> {
-
-    private static final String TYPE_LONG = "$numberLong";
-    private static final String VM_ID = "vmId";
-    private static final String AGENT_ID = "agentId";
-    private static final String MARKER = "marker";
-    private static final String JSON_PAYLOAD = "jsonPayload";
-    private static final String TIMESTAMP = "timeStamp";
-
-    @Override
-    public BytemanMetric read(JsonReader in) throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void write(JsonWriter out, BytemanMetric metric) throws IOException {
-        out.beginObject();
-        out.name(AGENT_ID);
-        out.value(metric.getAgentId());
-        out.name(VM_ID);
-        out.value(metric.getVmId());
-        out.name(MARKER);
-        out.value(metric.getMarker());
-        out.name(JSON_PAYLOAD);
-        out.value(metric.getDataAsJson());
-        out.name(TIMESTAMP);
-        writeLong(out, metric.getTimeStamp());
-        out.endObject();
-    }
-
-    private void writeLong(JsonWriter out, long value) throws IOException {
-        // Write MongoDB representation of a Long
-        out.beginObject();
-        out.name(TYPE_LONG);
-        out.value(String.valueOf(value));
-        out.endObject();
-    }
-
-}
--- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/LocaleResources.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common.internal;
-
-import com.redhat.thermostat.shared.locale.Translate;
-
-public enum LocaleResources {
-
-    REQUEST_FAILED_AUTH_ISSUE,
-    REQUEST_FAILED_UNKNOWN_ISSUE,
-    ERROR_UNKNOWN_RESPONSE,
-    ;
-    
-    static final String RESOURCE_BUNDLE = LocaleResources.class.getPackage().getName() + ".strings";
-
-    public static Translate<LocaleResources> createLocalizer() {
-        return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class);
-    }
-}
--- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanDAOImpl.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,183 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common.internal;
-
-import java.util.List;
-import java.util.logging.Logger;
-
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.Service;
-
-import com.redhat.thermostat.common.model.Range;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-import com.redhat.thermostat.storage.core.AgentId;
-import com.redhat.thermostat.storage.core.Category;
-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.VmId;
-import com.redhat.thermostat.storage.core.VmTimeIntervalPojoListGetter;
-import com.redhat.thermostat.storage.dao.AbstractDao;
-import com.redhat.thermostat.storage.dao.AbstractDaoQuery;
-import com.redhat.thermostat.storage.dao.AbstractDaoStatement;
-import com.redhat.thermostat.vm.byteman.common.BytemanMetric;
-import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO;
-import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus;
-
-@Component
-@Service(value = VmBytemanDAO.class)
-public class VmBytemanDAOImpl extends AbstractDao implements VmBytemanDAO {
-    
-    static final Key<String> MARKER = new Key<>("marker");
-    static final Key<String> DATA = new Key<>("data");
-    static final Key<String> RULE = new Key<>("rule");
-    static final Key<Integer> PORT = new Key<>("listenPort");
-    
-    static final Category<BytemanMetric> VM_BYTEMAN_METRICS_CATEGORY = new Category<>(
-            "vm-byteman-metrics",
-            BytemanMetric.class,
-            Key.AGENT_ID, Key.VM_ID, Key.TIMESTAMP,
-            MARKER, DATA);
-    
-    static final Category<VmBytemanStatus> VM_BYTEMAN_STATUS_CATEGORY = new Category<>(
-            "vm-byteman-status",
-            VmBytemanStatus.class,
-            Key.AGENT_ID, Key.VM_ID, Key.TIMESTAMP,
-            RULE, PORT);
-    
-    static final String REPLACE_OR_ADD_STATUS_DESC = "REPLACE " + VM_BYTEMAN_STATUS_CATEGORY.getName() +
-            " SET '" + Key.AGENT_ID.getName() + "' = ?s , " +
-                 "'" + Key.VM_ID.getName() + "' = ?s , " +
-                 "'" + Key.TIMESTAMP.getName() + "' = ?l , " +
-                 "'" + RULE.getName() + "' = ?s , " +
-                 "'" + PORT.getName() + "' = ?i WHERE "
-                         + "'" + Key.VM_ID.getName() + "' = ?s";
-    
-    static final String ADD_METRIC_DESC = "ADD " + VM_BYTEMAN_METRICS_CATEGORY.getName() +
-            " SET '" + Key.AGENT_ID.getName() + "' = ?s , " +
-                 "'" + Key.VM_ID.getName() + "' = ?s , " +
-                 "'" + Key.TIMESTAMP.getName() + "' = ?l , " +
-                 "'" + MARKER.getName() + "' = ?s , " +
-                 "'" + DATA.getName() + "' = ?s";
-    
-    static final String QUERY_VM_BYTEMAN_STATUS = "QUERY " + VM_BYTEMAN_STATUS_CATEGORY.getName() +
-            " WHERE '" + Key.VM_ID.getName() + "' = ?s LIMIT 1";
-    
-    @Reference
-    private Storage storage;
-    private VmTimeIntervalPojoListGetter<BytemanMetric> intervalGetter;
-    
-    public VmBytemanDAOImpl() {
-        // Default constructor for DS
-    }
-    
-    VmBytemanDAOImpl(Storage storage) {
-        this.storage = storage;
-    }
-    
-    @Activate
-    private void activate() {
-        storage.registerCategory(VM_BYTEMAN_METRICS_CATEGORY);
-        storage.registerCategory(VM_BYTEMAN_STATUS_CATEGORY);
-        intervalGetter = new VmTimeIntervalPojoListGetter<>(storage, VM_BYTEMAN_METRICS_CATEGORY);
-    }
-
-    @Override
-    public void addMetric(final BytemanMetric metric) {
-        executeStatement(new AbstractDaoStatement<BytemanMetric>(storage, VM_BYTEMAN_METRICS_CATEGORY, ADD_METRIC_DESC) {
-
-            @Override
-            public PreparedStatement<BytemanMetric> customize(PreparedStatement<BytemanMetric> preparedStatement) {
-                preparedStatement.setString(0, metric.getAgentId());
-                preparedStatement.setString(1, metric.getVmId());
-                preparedStatement.setLong(2, metric.getTimeStamp());
-                preparedStatement.setString(3, metric.getMarker());
-                preparedStatement.setString(4, metric.getDataAsJson());
-                return preparedStatement;
-            }
-        });
-
-    }
-
-    @Override
-    public List<BytemanMetric> findBytemanMetrics(Range<Long> timeRange,
-            VmId vmId, AgentId agentId) {
-        return intervalGetter.getLatest(agentId, vmId, timeRange.getMin(), timeRange.getMax());
-    }
-
-    @Override
-    protected Logger getLogger() {
-        return LoggingUtils.getLogger(VmBytemanDAOImpl.class);
-    }
-
-    @Override
-    public void addOrReplaceBytemanStatus(final VmBytemanStatus status) {
-        executeStatement(new AbstractDaoStatement<VmBytemanStatus>(storage, VM_BYTEMAN_STATUS_CATEGORY, REPLACE_OR_ADD_STATUS_DESC) {
-
-            @Override
-            public PreparedStatement<VmBytemanStatus> customize(PreparedStatement<VmBytemanStatus> preparedStatement) {
-                preparedStatement.setString(0, status.getAgentId());
-                preparedStatement.setString(1, status.getVmId());
-                preparedStatement.setLong(2, status.getTimeStamp());
-                preparedStatement.setString(3, status.getRule());
-                preparedStatement.setInt(4, status.getListenPort());
-                preparedStatement.setString(5, status.getVmId());
-                return preparedStatement;
-            }
-        });
-        
-    }
-
-    @Override
-    public VmBytemanStatus findBytemanStatus(final VmId vmId) {
-        List<VmBytemanStatus> result = executeQuery(new AbstractDaoQuery<VmBytemanStatus>(storage, VM_BYTEMAN_STATUS_CATEGORY, QUERY_VM_BYTEMAN_STATUS) {
-
-            @Override
-            public PreparedStatement<VmBytemanStatus> customize(PreparedStatement<VmBytemanStatus> preparedStatement) {
-                preparedStatement.setString(0, vmId.get());
-                return preparedStatement;
-            }
-        }).asList();
-        if (result.isEmpty()) {
-            return null;
-        }
-        return result.get(0);
-    }
-
-}
--- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanMetricDAOCategoryRegistration.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common.internal;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import com.redhat.thermostat.storage.core.auth.CategoryRegistration;
-
-public class VmBytemanMetricDAOCategoryRegistration
-        implements CategoryRegistration {
-
-    @Override
-    public Set<String> getCategoryNames() {
-        Set<String> categories = new HashSet<>(1);
-        categories.add(VmBytemanDAOImpl.VM_BYTEMAN_METRICS_CATEGORY.getName());
-        categories.add(VmBytemanDAOImpl.VM_BYTEMAN_STATUS_CATEGORY.getName());
-        return categories;
-    }
-
-}
--- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanMetricDAOImplStatementDescriptorRegistration.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common.internal;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import com.redhat.thermostat.storage.core.VmTimeIntervalPojoListGetter;
-import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration;
-
-public class VmBytemanMetricDAOImplStatementDescriptorRegistration
-        implements StatementDescriptorRegistration {
-    
-    static final String intervalDescriptor = String.format(
-            VmTimeIntervalPojoListGetter.VM_INTERVAL_QUERY_FORMAT,
-            VmBytemanDAOImpl.VM_BYTEMAN_METRICS_CATEGORY.getName());
-
-    @Override
-    public Set<String> getStatementDescriptors() {
-        Set<String> descs = new HashSet<>(7);
-        descs.add(VmBytemanDAOImpl.ADD_METRIC_DESC);
-        descs.add(intervalDescriptor);
-        descs.add(VmBytemanDAOImpl.REPLACE_OR_ADD_STATUS_DESC);
-        descs.add(VmBytemanDAOImpl.QUERY_VM_BYTEMAN_STATUS);
-        return descs;
-    }
-
-}
--- a/plugins/vm-byteman/common/src/main/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanStatusTypeAdapter.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common.internal;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus;
-
-import java.io.IOException;
-
-public class VmBytemanStatusTypeAdapter extends TypeAdapter<VmBytemanStatus> {
-
-    private static final String TYPE_LONG = "$numberLong";
-    private static final String VM_ID = "vmId";
-    private static final String AGENT_ID = "agentId";
-    private static final String TIMESTAMP = "timeStamp";
-    private static final String RULE = "rule";
-    private static final String LISTEN_PORT = "listenPort";
-
-    @Override
-    public VmBytemanStatus read(JsonReader in) throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void write(JsonWriter out, VmBytemanStatus status) throws IOException {
-        out.beginObject();
-        out.name(AGENT_ID);
-        out.value(status.getAgentId());
-        out.name(VM_ID);
-        out.value(status.getVmId());
-        out.name(TIMESTAMP);
-        writeLong(out, status.getTimeStamp());
-        out.name(RULE);
-        out.value(status.getRule());
-        out.name(LISTEN_PORT);
-        out.value(status.getListenPort());
-        out.endObject();
-    }
-
-    private void writeLong(JsonWriter out, long value) throws IOException {
-        // Write MongoDB representation of a Long
-        out.beginObject();
-        out.name(TYPE_LONG);
-        out.value(String.valueOf(value));
-        out.endObject();
-    }
-}
--- a/plugins/vm-byteman/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.CategoryRegistration	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-com.redhat.thermostat.vm.byteman.common.internal.VmBytemanMetricDAOCategoryRegistration
\ No newline at end of file
--- a/plugins/vm-byteman/common/src/main/resources/META-INF/services/com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-com.redhat.thermostat.vm.byteman.common.internal.VmBytemanMetricDAOImplStatementDescriptorRegistration
\ No newline at end of file
--- a/plugins/vm-byteman/common/src/main/resources/com/redhat/thermostat/vm/byteman/common/internal/strings.properties	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-REQUEST_FAILED_AUTH_ISSUE = Request failed due to authentication/authorization issues.
-REQUEST_FAILED_UNKNOWN_ISSUE = Request failed for some unknown reason.
-ERROR_UNKNOWN_RESPONSE = Unknown response: {0}
--- a/plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/BytemanMetricDataExtractorTest.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class BytemanMetricDataExtractorTest {
-
-    private BytemanMetricDataExtractor extractor;
-    
-    @Before
-    public void setup() {
-        extractor = new BytemanMetricDataExtractor();
-    }
-    
-    @Test
-    public void testEmptyKeySet() {
-        List<String> actual = extractor.getSortedKeySet();
-        assertTrue(actual.isEmpty());
-    }
-    
-    @Test
-    public void testAdditiveKeySet() {
-        String firstKey = "zoo";
-        BytemanMetric first = new BytemanMetric();
-        first.setData("{\"" + firstKey + "\": \"bar\"}");
-        extractor.mineMetric(first);
-        List<String> actual = extractor.getSortedKeySet();
-        assertEquals(1, actual.size());
-        assertEquals(firstKey, actual.get(0));
-        
-        BytemanMetric second = new BytemanMetric();
-        String secondKey = "secondKey";
-        second.setData("{\"" + secondKey + "\": \"baz\"}");
-        extractor.mineMetric(second);
-        actual = extractor.getSortedKeySet();
-        assertEquals(2, actual.size());
-        
-        // verify sorting
-        assertEquals(secondKey, actual.get(0));
-        assertEquals(firstKey, actual.get(1));
-    }
-    
-    @Test
-    public void testDuplicateKey() {
-        String firstKey = "zoo";
-        BytemanMetric first = new BytemanMetric();
-        first.setData("{\"" + firstKey + "\": \"bar\"}");
-        extractor.mineMetric(first);
-        List<String> actual = extractor.getSortedKeySet();
-        assertEquals(1, actual.size());
-        assertEquals(firstKey, actual.get(0));
-        
-        extractor.mineMetric(first);
-        actual = extractor.getSortedKeySet();
-        assertEquals(1, actual.size());
-        assertEquals(firstKey, actual.get(0));
-    }
-    
-    @Test
-    public void extractionDoesNotFailIfNoData() {
-        BytemanMetric m = new BytemanMetric();
-        extractor.mineMetric(m); // this shall not fail with NPE
-        List<String> actual = extractor.getSortedKeySet();
-        assertTrue(actual.isEmpty());
-    }
-    
-    @Test(expected = NullPointerException.class)
-    public void mineRequiresNonNull() {
-        extractor.mineMetric(null);
-    }
-    
-    @Test
-    public void canExtractListOfMetrics() {
-        String[] keys = new String[] {
-                "001_first", "002_second", "003_third", "004_fourth"
-        };
-        List<BytemanMetric> mList = buildMetrics(keys);
-        for (BytemanMetric metric: mList) {
-            extractor.mineMetric(metric);
-        }
-        List<String> keySet = extractor.getSortedKeySet();
-        assertEquals(4, keySet.size());
-        for (int i = 0; i < keySet.size(); i++) {
-            assertEquals(keys[0], keySet.get(0));
-        }
-        
-    }
-
-    private List<BytemanMetric> buildMetrics(String[] keys) {
-        List<BytemanMetric> list = new ArrayList<>();
-        for (String key: keys) {
-            BytemanMetric m = new BytemanMetric();
-            m.setData("{\"" + key + "\": \"" + key + "_value\"}");
-            list.add(m);
-        }
-        return list;
-    }
-}
--- a/plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/JsonHelper.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common;
-
-public class JsonHelper {
-
-    public static String buildJsonArray(int length) {
-        String elemFormat = 
-        "{\n" +
-                "    \"marker\": \"baz%d\",\n" +
-                "    \"timestamp\":\"%d\",\n" +
-                "    \"data\": {\n" +
-                "        \"foo1\": \"ba\\\"r1\",\n" +
-                "        \"foo2\": 42%d,\n" +
-                "        \"foo3\": 42.%d,\n" +
-                "        \"foo4\": false,\n" +
-                "        \"foo5\": \"[]\",\n" +
-                "        \"key\": null,\n" +
-                "        \"long\": 10000000001\n" +
-                "    }\n" +
-                "}";
-        StringBuilder builder = new StringBuilder();
-        builder.append("[");
-        for (int i = 0; i < length; i++) {
-            builder.append(String.format(elemFormat, i, 1234567890 + i, i, i));
-            builder.append(",");
-        }
-        if (length > 0) {
-            builder.deleteCharAt(builder.length() - 1);
-        }
-        builder.append("]");
-        return builder.toString();
-    }
-}
--- a/plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/command/BytemanRequestResponseListenerTest.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common.command;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import java.util.concurrent.CountDownLatch;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import com.redhat.thermostat.common.command.Request;
-import com.redhat.thermostat.common.command.Response;
-import com.redhat.thermostat.common.command.Response.ResponseType;
-import com.redhat.thermostat.vm.byteman.common.command.BytemanRequestResponseListener;
-
-public class BytemanRequestResponseListenerTest {
-
-    private BytemanRequestResponseListener listener;
-    private CountDownLatch latch;
-    
-    @Before
-    public void setup() {
-        latch = mock(CountDownLatch.class);
-        listener = new BytemanRequestResponseListener(latch);
-    }
-    
-    @Test
-    public void testAuthIssue() {
-        listener.fireComplete(mock(Request.class), new Response(ResponseType.AUTH_FAILED));
-        verify(latch).countDown();
-        assertTrue(listener.isError());
-        String errOut = listener.getErrorMessage(); 
-        assertTrue(errOut.contains("authentication"));
-        assertTrue(errOut.contains("issue"));
-    }
-    
-    @Test
-    public void testSuccess() {
-        listener.fireComplete(mock(Request.class), new Response(ResponseType.OK));
-        verify(latch).countDown();
-        assertFalse(listener.isError());
-    }
-    
-    @Test
-    public void testUnknownError() {
-        listener.fireComplete(mock(Request.class), new Response(ResponseType.ERROR));
-        verify(latch).countDown();
-        assertTrue(listener.isError());
-        String errOut = listener.getErrorMessage();
-        assertTrue(errOut.contains("unknown"));
-        assertTrue(errOut.contains("reason"));
-    }
-    
-    @Test
-    public void testUnknownType() {
-        listener.fireComplete(mock(Request.class), new Response(ResponseType.NOK));
-        verify(latch).countDown();
-        assertTrue(listener.isError());
-        String errOut = listener.getErrorMessage();
-        assertEquals("Unknown response: NOK", errOut);
-    }
-}
--- a/plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/command/BytemanRequestTest.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common.command;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-
-import java.net.InetSocketAddress;
-
-import org.junit.Test;
-
-import com.redhat.thermostat.common.command.Request;
-import com.redhat.thermostat.common.command.Request.RequestType;
-import com.redhat.thermostat.storage.model.VmInfo;
-import com.redhat.thermostat.vm.byteman.common.command.BytemanRequest.RequestAction;
-
-public class BytemanRequestTest {
-
-    @Test
-    public void testCreateRequestWithRule() {
-        Request req = BytemanRequest.create(new InetSocketAddress("127.0.0.1", 12000), mock(VmInfo.class), RequestAction.LOAD_RULES, 3, "foo-bar");
-        assertEquals(RequestType.RESPONSE_EXPECTED, req.getType());
-    }
-}
--- a/plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricTypeAdapterTest.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common.internal;
-
-import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.redhat.thermostat.vm.byteman.common.BytemanMetric;
-import com.redhat.thermostat.vm.byteman.common.BytemanMetricTypeAdapterFactory;
-import com.redhat.thermostat.vm.byteman.common.JsonHelper;
-
-public class BytemanMetricTypeAdapterTest {
-    
-    private static final double DELTA = 0.001;
-    
-    private Gson gson;
-    
-    @Before
-    public void setup() {
-        gson = new GsonBuilder()
-                .registerTypeAdapterFactory(new BytemanMetricTypeAdapterFactory())
-                .disableHtmlEscaping()
-                .serializeNulls()
-                .create();
-    }
-
-    @Test
-    public void canDeserializeArrayOfMetrics() {
-        String json = JsonHelper.buildJsonArray(10);
-        BytemanMetric[] metrics = gson.fromJson(json, BytemanMetric[].class);
-        assertEquals(10, metrics.length);
-        for (int i = 0; i < 10; i++) {
-            assertEquals("baz" + i, metrics[i].getMarker());
-            assertEquals(1234567890 + i, metrics[i].getTimeStamp());
-            Map<String, Object> dataAsMap = metrics[i].getDataAsMap();
-            assertFalse((Boolean)dataAsMap.get("foo4"));
-            assertEquals("[]", (String)dataAsMap.get("foo5"));
-            double foo3Val = (double)dataAsMap.get("foo3");
-            String foo3Str = String.format("42.%d", i);
-            double expectedFoo3Val = Double.parseDouble(foo3Str); 
-            assertEquals(expectedFoo3Val, foo3Val, DELTA);
-            double foo2Val = (double)dataAsMap.get("foo2");
-            String foo2Str = String.format("42%d.0", i);
-            double expectedFoo2Val = Double.parseDouble(foo2Str);
-            assertEquals(expectedFoo2Val, foo2Val, DELTA);
-            assertEquals("ba\"r1", (String)dataAsMap.get("foo1"));
-            assertEquals("Expected 7 key value pairs", 7, dataAsMap.keySet().size());
-            assertTrue(dataAsMap.containsKey("key"));
-            assertNull("value for \"key\" is null", dataAsMap.get("key"));
-            Double rawLong = (Double)dataAsMap.get("long");
-            long longVal = rawLong.longValue();
-            assertEquals(10_000_000_001L, longVal);
-        }
-    }
-    
-    /*
-     * This is a test which makes sure that html characters don't get
-     * escaped. We were seeing instances where the following happened which this
-     * test is trying to catch:
-     * 
-     * before JSON deserialization: {"key": "value = 'foo', 'bar', 'baz'"}
-     * after JSON deserialization: {"key"; "value \u003d \u0027foo\u0027, \u0027bar\u0027, \u0027baz\u0027"}
-     */
-    @Test
-    public void canDeserializeMetricWithSpecialChar() {
-        String json = "{\n" +
-                "    \"marker\": \"marker\",\n" +
-                "    \"timestamp\":\"30\",\n" +
-                "    \"data\": {\n" +
-                "        \"key\": \"value = 'foo', 'bar', 'baz'\"\n" +
-                "    }\n" +
-                "}";
-        BytemanMetric metric = gson.fromJson(json, BytemanMetric.class);
-        assertJsonEquals("{\"key\":\"value = 'foo', 'bar', 'baz'\"}", metric.getData());
-        Map<String, Object> dataAsMap = metric.getDataAsMap();
-        assertEquals("value = 'foo', 'bar', 'baz'", dataAsMap.get("key"));
-    }
-
-}
--- a/plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/BytemanMetricWebTypeAdapterTest.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common.internal;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.redhat.thermostat.vm.byteman.common.BytemanMetric;
-import org.junit.Test;
-
-import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals;
-
-public class BytemanMetricWebTypeAdapterTest {
-
-    @Test
-    public void testWrite() {
-        GsonBuilder builder = new GsonBuilder();
-        builder.registerTypeAdapter(BytemanMetric.class, new BytemanMetricWebTypeAdapter());
-        Gson gson = builder.create();
-        BytemanMetric metric = new BytemanMetric();
-        metric.setTimeStamp(100l);
-        metric.setVmId("Vm-1");
-        metric.setAgentId("Agent-1");
-        metric.setMarker("Marker");
-        metric.setData("{\"data\":\"This is data\"}");
-        assertJsonEquals("{\"agentId\":\"Agent-1\",\"vmId\":\"Vm-1\",\"marker\":\"Marker\",\"jsonPayload\":\"{\\\"data\\\":\\\"This is data\\\"}\",\"timeStamp\":{\"$numberLong\":\"100\"}}", gson.toJson(metric));
-    }
-}
--- a/plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/LocaleResourcesTest.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common.internal;
-
-import com.redhat.thermostat.testutils.AbstractLocaleResourcesTest;
-
-public class LocaleResourcesTest extends AbstractLocaleResourcesTest<LocaleResources> {
-
-    @Override
-    protected Class<LocaleResources> getEnumClass() {
-        return LocaleResources.class;
-    }
-
-    @Override
-    protected String getResourceBundle() {
-        return LocaleResources.RESOURCE_BUNDLE;
-    }
-
-}
--- a/plugins/vm-byteman/common/src/test/java/com/redhat/thermostat/vm/byteman/common/internal/VmBytemanStatusTypeAdapterTest.java	Mon Sep 18 14:04:16 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright 2012-2017 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.byteman.common.internal;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus;
-import org.junit.Test;
-
-import static com.redhat.thermostat.testutils.JsonUtils.assertJsonEquals;
-
-public class VmBytemanStatusTypeAdapterTest {
-
-    @Test
-    public void testWrite() {
-        GsonBuilder builder = new GsonBuilder();
-        builder.registerTypeAdapter(VmBytemanStatus.class, new VmBytemanStatusTypeAdapter());
-        Gson gson = builder.create();
-        VmBytemanStatus status = new VmBytemanStatus();
-        status.setTimeStamp(100l);
-        status.setAgentId("Agent-1");
-        status.setVmId("Vm-1");
-        status.setListenPort(27518);
-        status.setRule("Rule");
-        assertJsonEquals("{\"agentId\":\"Agent-1\",\"vmId\":\"Vm-1\",\"timeStamp\":{\"$numberLong\":\"100\"},\"rule\":\"Rule\",\"listenPort\":27518}", gson.toJson(status));
-    }
-
-}
--- a/plugins/vm-byteman/distribution/assemblies/plugin-assembly.xml	Mon Sep 18 14:04:16 2017 +0200
+++ b/plugins/vm-byteman/distribution/assemblies/plugin-assembly.xml	Fri Sep 22 10:10:52 2017 -0400
@@ -43,28 +43,34 @@
   <formats>
     <format>zip</format>
   </formats>
-  <baseDirectory>${thermostat.plugin}</baseDirectory>
-  <includeBaseDirectory>true</includeBaseDirectory>
+  <includeBaseDirectory>false</includeBaseDirectory>
  
   <dependencySets>
     <dependencySet>
       <includes>
-        <include>com.redhat.thermostat:thermostat-vm-byteman-common</include>
         <include>com.redhat.thermostat:thermostat-vm-byteman-agent</include>
         <include>org.jboss.byteman:byteman-submit</include>
         <include>org.jboss.byteman:byteman-install</include>
       </includes>
       <useProjectArtifact>false</useProjectArtifact>
       <useStrictFiltering>true</useStrictFiltering>
+      <outputDirectory>plugins/${thermostat.plugin}</outputDirectory>
     </dependencySet>
   </dependencySets>
   
-  <files>
-    <file>
-      <source>thermostat-plugin.xml</source>
-      <outputDirectory>/</outputDirectory>
+  <fileSets>
+    <fileSet>
+      <includes>
+        <include>thermostat-plugin.xml</include>
+      </includes>
+      <outputDirectory>plugins/${thermostat.plugin}</outputDirectory>
       <filtered>true</filtered>
-    </file>
-  </files>
+    </fileSet>
+    <fileSet>
+      <directory>configFiles</directory>
+      <outputDirectory>etc/plugins.d/${thermostat.plugin}</outputDirectory>
+      <filtered>true</filtered>
+    </fileSet>
+  </fileSets>
 </assembly>
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/vm-byteman/distribution/configFiles/gateway.properties	Fri Sep 22 10:10:52 2017 -0400
@@ -0,0 +1,2 @@
+# Web socket base URL to the commands microservice provided by the Thermostat web gateway
+gatewayURL=https://127.0.0.1:30000/jvm-byteman/0.0.1
--- a/plugins/vm-byteman/distribution/thermostat-plugin.xml	Mon Sep 18 14:04:16 2017 +0200
+++ b/plugins/vm-byteman/distribution/thermostat-plugin.xml	Fri Sep 22 10:10:52 2017 -0400
@@ -41,7 +41,6 @@
         <extension>
             <name>agent</name>
             <bundles>
-                <bundle><symbolic-name>com.redhat.thermostat.vm.byteman.common</symbolic-name><version>${project.version}</version></bundle>
                 <bundle><symbolic-name>com.redhat.thermostat.vm.byteman.agent</symbolic-name><version>${project.version}</version></bundle>
             </bundles>
         </extension>
--- a/plugins/vm-byteman/pom.xml	Mon Sep 18 14:04:16 2017 +0200
+++ b/plugins/vm-byteman/pom.xml	Fri Sep 22 10:10:52 2017 -0400
@@ -54,7 +54,6 @@
     <module>byteman-helper</module>
     <module>byteman-helper-distro</module>
     <module>agent</module>
-    <module>common</module>
     <module>distribution</module>
   </modules>