changeset 2568:b98beac5559c

refactor - move all os-specific code into a new package This patch moves most os-specific code to a new package, com.redhat.thermostat.common.portability. Most of the remaining code is Linux code that references the /proc filesystem; this code will be addressed in a separate patch. Reviewed by: ebaron Review thread: http://icedtea.classpath.org/pipermail/thermostat/2017-January/021916.html
author Simon Tooke <stooke@redhat.com>
date Mon, 23 Jan 2017 10:11:31 -0500
parents 4c926ce7235d
children 0c7e9a8854c6
files README.api agent/core/Makefile agent/core/pom.xml agent/core/src/main/java/com/redhat/thermostat/agent/internal/Activator.java agent/core/src/main/java/com/redhat/thermostat/agent/utils/ProcessChecker.java agent/core/src/main/java/com/redhat/thermostat/agent/utils/SysConf.java agent/core/src/main/java/com/redhat/thermostat/agent/utils/hostname/HostName.java agent/core/src/main/java/com/redhat/thermostat/agent/utils/linux/ProcDataSource.java agent/core/src/main/java/com/redhat/thermostat/agent/utils/username/UserNameLookupException.java agent/core/src/main/java/com/redhat/thermostat/agent/utils/username/UserNameUtil.java agent/core/src/main/java/com/redhat/thermostat/agent/utils/username/package-info.java agent/core/src/main/java/com/redhat/thermostat/agent/utils/windows/WindowsHelperImpl.java agent/core/src/main/java/com/redhat/thermostat/backend/internal/VmMonitor.java agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/AgentProxyClient.java agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImpl.java agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/ProcessUserInfoBuilder.java agent/core/src/main/java/com/redhat/thermostat/utils/username/internal/UserNameUtilImpl.java agent/core/src/main/native/HostName.c agent/core/src/main/native/UserNameUtilImpl.c agent/core/src/main/native/WindowsHelperImpl.c agent/core/src/test/java/com/redhat/thermostat/agent/internal/ActivatorTest.java agent/core/src/test/java/com/redhat/thermostat/agent/utils/ProcessCheckerTest.java agent/core/src/test/java/com/redhat/thermostat/agent/utils/SysConfTest.java agent/core/src/test/java/com/redhat/thermostat/agent/utils/linux/ProcDataSourceTest.java agent/core/src/test/java/com/redhat/thermostat/agent/utils/windows/WindowsHelperImplTest.java agent/core/src/test/java/com/redhat/thermostat/backend/internal/VmMonitorTest.java agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImplTest.java agent/ipc/server/pom.xml agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/IPCConfigurationWriter.java common/pom.xml common/portability/Makefile common/portability/pom.xml common/portability/src/main/java/com/redhat/thermostat/common/portability/HostName.java common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableHost.java common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableHostImpl.java common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableMemoryStat.java common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcess.java common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcessImpl.java common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcessStat.java common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableVmIoStat.java common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessChecker.java common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessUserInfo.java common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessUserInfoBuilder.java common/portability/src/main/java/com/redhat/thermostat/common/portability/SysConf.java common/portability/src/main/java/com/redhat/thermostat/common/portability/UserNameLookupException.java common/portability/src/main/java/com/redhat/thermostat/common/portability/UserNameUtil.java common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/Activator.java common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/UnimplementedError.java common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxProcessImpl.java common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxProcessUserInfoBuilderImpl.java common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/UserNameUtilImpl.java common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImpl.java common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHostImpl.java common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsMemoryStat.java common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsProcessImpl.java common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsUserInfoBuilderImpl.java common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsVmIoStat.java common/portability/src/main/java/com/redhat/thermostat/common/portability/linux/ProcDataSource.java common/portability/src/main/java/com/redhat/thermostat/common/portability/package-info.java common/portability/src/main/native/HostName.c common/portability/src/main/native/UserNameUtilImpl.c common/portability/src/main/native/WindowsHelperImpl.c common/portability/src/test/java/com/redhat/thermostat/common/portability/ProcessCheckerTest.java common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/ActivatorTest.java common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/SysConfTest.java common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/LinuxProcessUserInfoBuilderImplTest.java common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImplTest.java common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/windows/WindowsProcessUserInfoBuilderTest.java common/portability/src/test/java/com/redhat/thermostat/common/portability/linux/ProcDataSourceTest.java distribution/assembly/core-assembly-windows.xml distribution/assembly/core-assembly.xml distribution/packaging/fedora/thermostat.spec distribution/pom.xml distribution/windows/scripts/thermostat-agent-proxy.cmd distribution/windows/scripts/thermostat-common.cmd distribution/windows/scripts/thermostat-webservice.cmd host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatBuilder.java host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/agent/internal/HostCpuBackend.java host-cpu/agent/src/test/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatBuilderTest.java host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/agent/internal/HostMemoryBackend.java host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatBuilder.java host-memory/agent/src/test/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatBuilderTest.java numa/agent/src/main/java/com/redhat/thermostat/numa/agent/internal/NumaWindowsCollectorImpl.java process-handler/pom.xml process-handler/src/main/java/com/redhat/thermostat/service/internal/ProcessUtilitiesBase.java process-handler/src/main/java/com/redhat/thermostat/service/internal/windows/WindowsProcessUtilities.java process-handler/src/test/java/com/redhat/thermostat/service/internal/windows/WindowsProcessUtilitiesTest.java system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/JvmStatHostListener.java system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/SystemBackend.java system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/SystemBackendActivator.java system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/HostInfoBuilderImpl.java system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/LinuxInfoBuilderFactory.java system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/ProcessEnvironmentBuilderImpl.java system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/ProcessUserInfoBuilderImpl.java system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/models/InfoBuilderFactory.java system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/models/ProcessUserInfo.java system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/models/ProcessUserInfoBuilder.java system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsHostInfoBuilderImpl.java system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsInfoBuilderFactory.java system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsProcessEnvironmentBuilderImpl.java system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsUserInfoBuilderImpl.java system-backend/src/main/native/WindowsHelperImpl.c system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/JvmStatHostListenerTest.java system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/SystemBackendTest.java system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/HostInfoBuilderTest.java system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/ProcessEnvironmentBuilderTest.java system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/ProcessUserInfoBuilderTest.java system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsHostInfoBuilderTest.java system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsInfoBuilderFactoryTest.java system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsProcessEnvironmentBuilderTest.java system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsProcessUserInfoBuilderTest.java vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManager.java vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacher.java vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiver.java vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/ProcessUserInfoBuilder.java vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManagerTest.java vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacherTest.java vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/LinuxProcessStatusInfoBuilderImpl.java vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/VmCpuBackend.java vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/WindowsProcessStatusInfoBuilderImpl.java vm-cpu/agent/src/test/java/com/redhat/thermostat/vm/cpu/agent/internal/LinuxProcessStatusInfoBuilderTest.java vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/LinuxVmIoStatBuilder.java vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/ProcIoDataReader.java vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoBackend.java vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatBuilder.java vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/WindowsVmIoStatBuilder.java vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/LinuxVmIoStatBuilderTest.java vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/ProcIoDataReaderTest.java vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/VmIoBackendTest.java vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatBuilderTest.java vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/WindowsVmIoStatBuilderTest.java
diffstat 131 files changed, 4407 insertions(+), 3090 deletions(-) [+]
line wrap: on
line diff
--- a/README.api	Fri Jan 20 10:48:09 2017 -0500
+++ b/README.api	Mon Jan 23 10:11:31 2017 -0500
@@ -7,9 +7,7 @@
  - com.redhat.thermostat.agent.command
  - com.redhat.thermostat.agent.config
  - com.redhat.thermostat.agent.utils
- - com.redhat.thermostat.agent.utils.hostname
  - com.redhat.thermostat.agent.utils.management
- - com.redhat.thermostat.agent.utils.username
  - com.redhat.thermostat.annotations
  - com.redhat.thermostat.backend
  - com.redhat.thermostat.client.cli
@@ -27,6 +25,7 @@
  - com.redhat.thermostat.common.command
  - com.redhat.thermostat.common.config
  - com.redhat.thermostat.common.model
+ - com.redhat.thermostat.common.portability
  - com.redhat.thermostat.common.ssl
  - com.redhat.thermostat.common.tools
  - com.redhat.thermostat.common.utils
--- a/agent/core/Makefile	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-CC         = gcc
-JAVAH      = javah
-MYCFLAGS   = -c -Wall $(EXTRA_CFLAGS)
-MYLDFLAGS  = -shared $(EXTRA_CFLAGS)
-COPY       = cp -a
-
-CLASSPATH  = target/classes/
-TARGET_DIR = target
-
-ifeq ($(OS),Windows_NT)
-    JNI_PLATFORM = win32
-    SO_PREFIX  =
-    SO_SUFFIX  = .dll
-else
-    JNI_PLATFORM = linux
-    SO_PREFIX  = lib
-    SO_SUFFIX  = .so
-    MYCFLAGS   += -fPIC
-    MYLDFLAGS  += -fPIC
-endif
-
-INCLUDE    = -I $(TARGET_DIR) -I "$(JAVA_HOME)/include/" -I "$(JAVA_HOME)/include/$(JNI_PLATFORM)"
-
-HOSTNAME_SOURCES    = src/main/native/HostName.c
-HOSTNAME_TARGET     = $(TARGET_DIR)/HostName.c
-HOSTNAME_OBJECTS    = $(HOSTNAME_TARGET:.c=.o)
-HOSTNAME_EXECUTABLE = $(SO_PREFIX)HostNameWrapper$(SO_SUFFIX)
-
-USERNAME_SOURCES    = src/main/native/UserNameUtilImpl.c
-USERNAME_TARGET     = $(TARGET_DIR)/UserNameUtilImpl.c
-USERNAME_OBJECTS    = $(USERNAME_TARGET:.c=.o)
-USERNAME_EXECUTABLE = $(SO_PREFIX)UserNameUtilWrapper$(SO_SUFFIX)
-
-WINHELPER_SOURCES    = src/main/native/WindowsHelperImpl.c
-WINHELPER_TARGET     = $(TARGET_DIR)/WindowsHelperImpl.c
-WINHELPER_OBJECTS    = $(WINHELPER_TARGET:.c=.o)
-WINHELPER_EXECUTABLE = $(SO_PREFIX)WindowsHelperWrapper$(SO_SUFFIX)
-
-EXECUTABLES          = $(HOSTNAME_EXECUTABLE) $(USERNAME_EXECUTABLE)
-
-.PHONY:
-JNI_LIST = com.redhat.thermostat.agent.utils.hostname.HostName\
- com.redhat.thermostat.utils.username.internal.UserNameUtilImpl
-
-ifeq ($(OS),Windows_NT)
-    EXECUTABLES  += $(WINHELPER_EXECUTABLE)
-    JNI_LIST     +=  com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl
-endif
-
-$(JNI_LIST):
-	$(JAVAH) -force -classpath $(CLASSPATH) -d $(TARGET_DIR) $(JNI_LIST)
-
-all: $(JNI_LIST) init $(HOSTNAME_SOURCES) $(USERNAME_SOURCES) $(WINHELPER_SOURCES) $(EXECUTABLES)
-
-.PHONY:
-init:
-	$(COPY) $(HOSTNAME_SOURCES) $(HOSTNAME_TARGET)
-	$(COPY) $(USERNAME_SOURCES) $(USERNAME_TARGET)
-	$(COPY) $(WINHELPER_SOURCES) $(WINHELPER_TARGET)
-
-$(HOSTNAME_EXECUTABLE): $(HOSTNAME_OBJECTS)
-	$(CC) $(MYLDFLAGS) $(LDFLAGS) $(HOSTNAME_OBJECTS) $(PLATFORM_LIBS) -o $(TARGET_DIR)/$@
-	
-$(USERNAME_EXECUTABLE): $(USERNAME_OBJECTS)
-	$(CC) $(MYLDFLAGS) $(LDFLAGS) $(USERNAME_OBJECTS) $(PLATFORM_LIBS) -o $(TARGET_DIR)/$@
-
-$(WINHELPER_EXECUTABLE): $(WINHELPER_OBJECTS)
-	$(CC) $(MYLDFLAGS) $(LDFLAGS) $(WINHELPER_OBJECTS) $(PLATFORM_LIBS) -l psapi -o $(TARGET_DIR)/$@
-
-.c.o:
-	$(CC) $(MYCFLAGS) $(CFLAGS) $(INCLUDE) $< -o $@
-
-.cpp.o:
-	$(CC) $(MYCFLAGS) $(CFLAGS) $(INCLUDE) $< -o $@
-
-
-clean-lib:
-	rm -f $(TARGET_DIR)/$(HOSTNAME_EXECUTABLE)
-	rm -f $(TARGET_DIR)/$(USERNAME_EXECUTABLE)
-	rm -f $(TARGET_DIR)/$(WINHELPER_EXECUTABLE)
-	
-clean-obj:
-	rm -f $(HOSTNAME_OBJECTS) $(HOSTNAME_TARGET)
-	rm -f $(USERNAME_OBJECTS) $(USERNAME_TARGET)
-	rm -f $(WINHELPER_OBJECTS) $(WINHELPER_TARGET)
-	
-clean: clean-obj clean-lib
-	
--- a/agent/core/pom.xml	Fri Jan 20 10:48:09 2017 -0500
+++ b/agent/core/pom.xml	Mon Jan 23 10:11:31 2017 -0500
@@ -50,37 +50,6 @@
 
   <name>Thermostat Agent Core</name>
 
-  <profiles>
-    <profile>
-      <id>default</id>
-      <activation>
-        <activeByDefault>true</activeByDefault>
-      </activation>
-    </profile>
-
-    <profile>
-      <id>linux</id>
-      <activation>
-        <os><family>Unix</family></os>
-      </activation>
-      <properties>
-        <platform.libs></platform.libs>
-      </properties>
-    </profile>
-
-    <profile>
-      <id>windows</id>
-      <activation>
-        <os><family>Windows</family></os>
-      </activation>
-      <properties>
-        <platform.libs>-lws2_32</platform.libs>
-        <sharedlib.prefix></sharedlib.prefix>
-        <sharedlib.suffix>.dll</sharedlib.suffix>
-      </properties>
-    </profile>
-  </profiles>
-
   <dependencies>
     <dependency>
       <groupId>junit</groupId>
@@ -105,6 +74,11 @@
     </dependency>
     <dependency>
       <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-portability</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
       <artifactId>thermostat-launcher</artifactId>
       <version>${project.version}</version>
     </dependency>
@@ -145,21 +119,16 @@
             <Bundle-SymbolicName>com.redhat.thermostat.agent.core</Bundle-SymbolicName>
             <Bundle-Activator>com.redhat.thermostat.agent.internal.Activator</Bundle-Activator>
             <Export-Package>
-              com.redhat.thermostat.agent,
-              com.redhat.thermostat.agent.config,
-              com.redhat.thermostat.agent.utils,
-              com.redhat.thermostat.agent.utils.hostname,
-              com.redhat.thermostat.agent.utils.linux,
-              com.redhat.thermostat.agent.utils.management,
-              com.redhat.thermostat.agent.utils.username,
-              com.redhat.thermostat.agent.utils.windows,
-              com.redhat.thermostat.backend,
+                com.redhat.thermostat.agent,
+                com.redhat.thermostat.agent.config,
+                com.redhat.thermostat.agent.utils,
+                com.redhat.thermostat.agent.utils.management,
+                com.redhat.thermostat.backend
             </Export-Package>
             <Private-Package>
               com.redhat.thermostat.agent.internal,
               com.redhat.thermostat.backend.internal,
-              com.redhat.thermostat.utils.management.internal,
-              com.redhat.thermostat.utils.username.internal,
+              com.redhat.thermostat.utils.management.internal
             </Private-Package>
             <!-- Do not autogenerate uses clauses in Manifests -->
             <_nouses>true</_nouses>
@@ -176,38 +145,9 @@
             </systemPropertyVariables>
           </configuration>
       </plugin>
-      
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>exec-maven-plugin</artifactId>
-        <executions>  
-          <execution>
-            <phase>compile</phase>
-            <goals>
-              <goal>exec</goal>
-            </goals>
-          </execution>  
-        </executions>
-        <configuration>
-          <executable>make</executable>
-          <arguments>
-            <argument>all</argument>
-            <argument>CC=${c.compiler}</argument>
-            <argument>SO_PREFIX=${sharedlib.prefix}</argument>
-            <argument>SO_SUFFIX=${sharedlib.suffix}</argument>
-            <argument>EXTRA_CFLAGS=${cflags}</argument>
-            <argument>JNI_PLATFORM=${jni.platform}</argument>
-            <argument>PLATFORM_LIBS=${platform.libs}</argument>
-          </arguments>
-          <systemProperties>
-            <systemProperty>
-              <key>JAVA_HOME</key>
-              <value>${java.home}</value>
-            </systemProperty>
-          </systemProperties>
-        </configuration>
-      </plugin>
+
     </plugins>
+
     <pluginManagement>
       <plugins>
         <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
@@ -227,7 +167,7 @@
                     </goals>
                   </pluginExecutionFilter>
                   <action>
-                    <ignore></ignore>
+                    <ignore/>
                   </action>
                 </pluginExecution>
               </pluginExecutions>
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/internal/Activator.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/agent/core/src/main/java/com/redhat/thermostat/agent/internal/Activator.java	Mon Jan 23 10:11:31 2017 -0500
@@ -50,7 +50,7 @@
 import com.redhat.thermostat.agent.config.AgentConfigsUtils;
 import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
 import com.redhat.thermostat.agent.utils.management.MXBeanConnectionPool;
-import com.redhat.thermostat.agent.utils.username.UserNameUtil;
+import com.redhat.thermostat.common.portability.UserNameUtil;
 import com.redhat.thermostat.common.MultipleServiceTracker;
 import com.redhat.thermostat.common.MultipleServiceTracker.Action;
 import com.redhat.thermostat.common.MultipleServiceTracker.DependencyProvider;
@@ -62,7 +62,6 @@
 import com.redhat.thermostat.utils.management.internal.AgentProxyFilter;
 import com.redhat.thermostat.utils.management.internal.MXBeanConnectionPoolControl;
 import com.redhat.thermostat.utils.management.internal.MXBeanConnectionPoolImpl;
-import com.redhat.thermostat.utils.username.internal.UserNameUtilImpl;
 
 public class Activator implements BundleActivator {
     
@@ -75,10 +74,6 @@
     @Override
     public void start(final BundleContext context) throws Exception {
         
-        // No deps, register immediately
-        UserNameUtilImpl usernameUtil = new UserNameUtilImpl();
-        context.registerService(UserNameUtil.class, usernameUtil, null);
-        
         // Track common paths separately and register storage credentials quickly
         // We need to do this since otherwise no storage credentials will be
         // available by the time they're used in DbService
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/utils/ProcessChecker.java	Fri Jan 20 10:48:09 2017 -0500
+++ /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.agent.utils;
-
-import java.io.File;
-/**
- * Utility for checking whether a process exists or not.
- * 
- * Implementation note: This is Linux specific.
- *
- */
-public class ProcessChecker {
-
-    public boolean exists(int pid) {
-        File procFile = mapToFile(pid);
-        return procFile.exists();
-    }
-    
-    // testing-hook
-    File mapToFile(int pid) {
-        return new File("/proc/" + pid);
-    }
-    
-}
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/utils/SysConf.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +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.agent.utils;
-
-import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl;
-import com.redhat.thermostat.shared.config.OS;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-/**
- * A wrapper over POSIX's sysconf.
- * <p>
- * Implementation notes: uses {@code getconf(1)}
- */
-public class SysConf {
-
-    private SysConf() {
-        /* do not initialize */
-    }
-
-    public static long getClockTicksPerSecond() {
-        return OS.IS_LINUX ? getLinuxClockTicksPerSecond() : getWindowsClockTicksPerSecond();
-    }
-
-    private static long getWindowsClockTicksPerSecond() {
-        return WindowsHelperImpl.INSTANCE.getClockTicksPerSecond();
-    }
-
-    public static long getLinuxClockTicksPerSecond() {
-        String ticks = sysConf("CLK_TCK");
-        try {
-            return Long.valueOf(ticks);
-        } catch (NumberFormatException nfe) {
-            return 0;
-        }
-    }
-
-    private static String sysConf(String arg) {
-        try {
-            Process process = Runtime.getRuntime().exec(new String[] { "getconf", arg });
-            int result = process.waitFor();
-            if (result != 0) {
-                return null;
-            }
-            try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
-                return reader.readLine();
-            }
-        } catch (IOException | InterruptedException e) {
-            return null;
-        }
-    }
-}
-
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/utils/hostname/HostName.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +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.agent.utils.hostname;
-
-import com.redhat.thermostat.shared.config.NativeLibraryResolver;
-
-/**
- * Finds the current host name without doing a DNS lookup
- */
-public class HostName {
-
-    static {
-        String lib = NativeLibraryResolver.getAbsoluteLibraryPath("HostNameWrapper");
-        System.load(lib);
-    }
-    
-    public static String getLocalHostName() {
-        return getHostName();
-    }
-    
-    private static native String getHostName();
-}
-
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/utils/linux/ProcDataSource.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +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.agent.utils.linux;
-
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.Reader;
-
-/**
- * Wrapper for files under {@code /proc/}. See proc(5) for details about this.
- */
-public class ProcDataSource {
-
-    private static final String LOAD_FILE = "/proc/loadavg";
-    private static final String STAT_FILE = "/proc/stat";
-    private static final String MEMINFO_FILE = "/proc/meminfo";
-    private static final String CPUINFO_FILE = "/proc/cpuinfo";
-
-    private static final String PID_ENVIRON_FILE = "/proc/${pid}/environ";
-    private static final String PID_IO_FILE = "/proc/${pid}/io";
-    private static final String PID_STAT_FILE = "/proc/${pid}/stat";
-    private static final String PID_STATUS_FILE = "/proc/${pid}/status";
-
-    /**
-     * Returns a reader for /proc/cpuinfo
-     */
-    public Reader getCpuInfoReader() throws IOException {
-        return new FileReader(CPUINFO_FILE);
-    }
-
-    /**
-     * Returns a reader for /proc/loadavg
-     */
-    public Reader getCpuLoadReader() throws IOException {
-        return new FileReader(LOAD_FILE);
-    }
-
-    /**
-     * Returns a reader for /proc/stat. Kernel/System statistics.
-     */
-    public Reader getStatReader() throws IOException {
-        return new FileReader(STAT_FILE);
-    }
-
-    /**
-     * Returns a reader for /proc/meminfo
-     */
-    public Reader getMemInfoReader() throws IOException {
-        return new FileReader(MEMINFO_FILE);
-    }
-
-    /**
-     * Returns a reader for /proc/$PID/environ
-     */
-    public Reader getEnvironReader(int pid) throws IOException {
-        return new FileReader(getPidFile(PID_ENVIRON_FILE, pid));
-    }
-
-    /**
-     * Returns a reader for /proc/$PID/io
-     */
-    public Reader getIoReader(int pid) throws IOException {
-        return new FileReader(getPidFile(PID_IO_FILE, pid));
-    }
-
-    /**
-     * Returns a reader for /proc/$PID/stat
-     */
-    public Reader getStatReader(int pid) throws IOException {
-        return new FileReader(getPidFile(PID_STAT_FILE, pid));
-    }
-    
-    /**
-     * Returns a reader for /proc/$PID/status
-     */
-    public Reader getStatusReader(int pid) throws IOException {
-        return new FileReader(getPidFile(PID_STATUS_FILE, pid));
-    }
-
-    private String getPidFile(String fileName, int pid) {
-        return fileName.replace("${pid}", Integer.toString(pid));
-    }
-
-}
-
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/utils/username/UserNameLookupException.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +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.agent.utils.username;
-
-/**
- * 
- * Thrown on user name lookup error.
- *
- * @see UserNameUtil
- */
-@SuppressWarnings("serial")
-public class UserNameLookupException extends Exception {
-
-    public UserNameLookupException(Throwable cause) {
-        super(cause);
-    }
-}
-
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/utils/username/UserNameUtil.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +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.agent.utils.username;
-
-import com.redhat.thermostat.annotations.Service;
-
-/**
- * Utility to query the operating system for a user name.
- */
-@Service
-public interface UserNameUtil {
-
-    /**
-     * Gets the user name corresponding to the provided UID.
-     * 
-     * @param uid
-     *            The UID whose name to return.
-     * @throws UserNameLookupException
-     *            If an error occurred during retrieval of the user name.
-     * @return The user name if found. null if no such UID exists.
-     */
-    String getUserName(long uid) throws UserNameLookupException;
-
-}
-
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/utils/username/package-info.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +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.
- */
-
-
-/**
- * Utilities to help with username lookups
- */
-package com.redhat.thermostat.agent.utils.username;
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/utils/windows/WindowsHelperImpl.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,260 +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.agent.utils.windows;
-
-import com.redhat.thermostat.common.utils.LoggingUtils;
-import com.redhat.thermostat.shared.config.NativeLibraryResolver;
-import com.redhat.thermostat.shared.config.OS;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Logger;
-
-/**
- * Utility class to access Windows native code
- */
-public class WindowsHelperImpl {
-
-    private static final Logger logger = LoggingUtils.getLogger(WindowsHelperImpl.class);
-
-    /*
-     // from MemoryStatusEx (8 values)
-        DWORD     dwMemoryLoad;
-        DWORDLONG ullTotalPhys;
-        DWORDLONG ullAvailPhys;
-        DWORDLONG ullTotalPageFile;
-        DWORDLONG ullAvailPageFile;
-        DWORDLONG ullTotalVirtual;
-        DWORDLONG ullAvailVirtual;
-        DWORDLONG ullAvailExtendedVirtual;
-
-     // from PERFORMANCE_INFORMATION (13 values)
-        SIZE_T CommitTotal;
-        SIZE_T CommitLimit;
-        SIZE_T CommitPeak;
-        SIZE_T PhysicalTotal;
-        SIZE_T PhysicalAvailable;
-        SIZE_T SystemCache;
-        SIZE_T KernelTotal;
-        SIZE_T KernelPaged;
-        SIZE_T KernelNonpaged;
-        SIZE_T PageSize;
-        DWORD  HandleCount;
-        DWORD  ProcessCount;
-        DWORD  ThreadCount;
-     */
-
-    static {
-        if (OS.IS_WINDOWS) {
-            String lib = NativeLibraryResolver.getAbsoluteLibraryPath("WindowsHelperWrapper");
-            try {
-                System.load(lib);
-                INSTANCE = new WindowsHelperImpl();
-            } catch (UnsatisfiedLinkError e) {
-                logger.severe("Could not load WindowsHelperImpl DLL:" + lib);
-                INSTANCE = null;
-                // do not throw here, because you'll get a NoClassDefFound thrown when running other tests that Mock this class
-            }
-        } else {
-            INSTANCE = null;
-        }
-    }
-
-    public static class MemoryStat {
-
-        private final long timeStamp;
-        private final long total;
-        private final long free;
-        private final long buffers;
-        private final long cached;
-        private final long swapTotal;
-        private final long swapFree;
-        private final long commitLimit;
-
-
-        public MemoryStat() {
-            final long[] info = INSTANCE.getMemoryInfo();
-            this.timeStamp = System.currentTimeMillis();
-            this.total = info[1];
-            this.free = info[2];
-            this.buffers = 0;
-            this.cached = 0;
-            this.swapTotal = 3;
-            this.swapFree = 4;
-            this.commitLimit = 0;
-            // TODO - buffers, cached and commitLimit
-        }
-
-        public MemoryStat(long timeStamp, long total, long free, long buffers, long cached, long swapTotal, long swapFree, long commitLimit) {
-            this.timeStamp = timeStamp;
-            this.total = total;
-            this.free = free;
-            this.buffers = buffers;
-            this.cached = cached;
-            this.swapTotal = swapTotal;
-            this.swapFree = swapFree;
-            this.commitLimit = commitLimit;
-        }
-
-        public long getTimeStamp() {
-            return timeStamp;
-        }
-        public long getTotal() {
-            return total;
-        }
-        public long getFree() {
-            return free;
-        }
-        public long getBuffers() {
-            return buffers;
-        }
-        public long getCached() {
-            return cached;
-        }
-        public long getSwapTotal() {
-            return swapTotal;
-        }
-        public long getSwapFree() {
-            return swapFree;
-        }
-        public long getCommitLimit() {
-            return commitLimit;
-        }
-    }
-
-    public static WindowsHelperImpl INSTANCE;
-
-    private WindowsHelperImpl() {
-    }
-    // local host-wide information
-
-    public String getHostName() {
-        return getHostName0(true);
-    }
-
-    public String getOSName() {
-        return System.getProperty("os.name");
-    }
-
-    public String getOSVersion() {
-        final long info[] = new long[3];  // major, minor, build
-        getOSVersion0(info);
-        return "" + info[0] + "." + info[1] + " (Build " + info[2] + ")";
-    }
-
-    public String getCPUModel() {
-        return getCPUString0();
-    }
-
-    public int getCPUCount() {
-        return getCPUCount0();
-    }
-
-    public long getTotalMemory() {
-        final long info[] = getMemoryInfo();
-        return info[1]; // totalPhysical
-    }
-
-    // local process-specific information
-    public String getUserName(int pid) {
-        return getUserName0(pid,true);
-    }
-
-    public int getUid(int pid) {
-        return getUid0(pid);
-    }
-
-    public Map<String, String> getEnvironment(int pid) {
-        // the environment is returned as a 1D array of alternating env names and values
-        final String[] envArray = getEnvironment0(pid);
-        if (envArray == null || envArray.length == 0) {
-            return Collections.emptyMap();
-        }
-
-        if (envArray.length % 2 != 0) {
-            throw new AssertionError("environment array length not even");
-        }
-
-        final Map<String, String> env = new HashMap<>(envArray.length/2);
-        for (int i = 0; i < envArray.length / 2; i++) {
-            env.put(envArray[i * 2], envArray[i * 2 + 1]);
-        }
-        return env;
-    }
-
-    public long[] getProcessCPUInfo(int pid) {
-        final long[] info = new long[4];
-        getProcessInfo0(pid, info);
-        return info;
-    }
-
-    public long[] getProcessMemInfo(int pid) {
-        final long[] info = new long[4];
-        getProcessInfo0(pid, info);
-        return info;
-    }
-
-
-    private long[] getMemoryInfo() {
-        final long[] mi = new long[8];
-        getGlobalMemoryStatus0(mi);
-        return mi;
-    }
-
-    private long[] getPerformanceInfo() {
-        final long[] mi = new long[13];
-        getPerformanceInfo0(mi);
-        return mi;
-    }
-
-    public long getClockTicksPerSecond() {
-        return getClockTicksPerSecond0();
-    }
-
-    private static native String getHostName0(boolean prependDomain);
-    private static native void getOSVersion0(long[] versionAndBuild);
-    private static native int getUid0(int pid);
-    private static native String getUserName0(int pid, boolean prependDomain);
-    private static native String[] getEnvironment0(int pid);
-    private static native boolean getGlobalMemoryStatus0(long[] info);
-    private static native boolean getPerformanceInfo0(long[] info);
-    private static native boolean getProcessInfo0(int pid, long[] info);
-    private static native String getCPUString0();
-    private static native int getCPUCount0();
-    private static native long getClockTicksPerSecond0();
-}
--- a/agent/core/src/main/java/com/redhat/thermostat/backend/internal/VmMonitor.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/agent/core/src/main/java/com/redhat/thermostat/backend/internal/VmMonitor.java	Mon Jan 23 10:11:31 2017 -0500
@@ -48,7 +48,7 @@
 import sun.jvmstat.monitor.MonitoredVm;
 import sun.jvmstat.monitor.VmIdentifier;
 
-import com.redhat.thermostat.agent.utils.ProcessChecker;
+import com.redhat.thermostat.common.portability.ProcessChecker;
 import com.redhat.thermostat.backend.VmUpdateListener;
 import com.redhat.thermostat.common.Pair;
 import com.redhat.thermostat.common.utils.LoggingUtils;
--- a/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/AgentProxyClient.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/AgentProxyClient.java	Mon Jan 23 10:11:31 2017 -0500
@@ -40,6 +40,7 @@
 import java.io.IOException;
 
 import com.redhat.thermostat.common.ExitStatus;
+import com.redhat.thermostat.shared.config.OS;
 
 class AgentProxyClient {
     
@@ -68,7 +69,9 @@
     void runProcess() throws IOException, InterruptedException {
         // Start the agent proxy
         String serverPath = binPath + File.separator + SERVER_NAME;
-        String[] args = new String[] { serverPath, String.valueOf(pid), username, ipcConfigFile.getAbsolutePath(), serverName };
+        String[] args = OS.IS_UNIX
+                ? new String[] { serverPath, String.valueOf(pid), username, ipcConfigFile.getAbsolutePath(), serverName }
+                : new String[] { "cmd", "/C", serverPath+".cmd", String.valueOf(pid), username, ipcConfigFile.getAbsolutePath(), serverName };
         ProcessBuilder builder = new ProcessBuilder(args);
         builder.inheritIO();
         Process proxy = procCreator.startProcess(builder);
--- a/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImpl.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImpl.java	Mon Jan 23 10:11:31 2017 -0500
@@ -59,12 +59,13 @@
 import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
 import com.redhat.thermostat.agent.ipc.server.IPCMessage;
 import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks;
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.ProcessUserInfo;
+import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
 import com.redhat.thermostat.agent.utils.management.MXBeanConnection;
 import com.redhat.thermostat.agent.utils.management.MXBeanConnectionException;
 import com.redhat.thermostat.agent.utils.management.MXBeanConnectionPool;
-import com.redhat.thermostat.agent.utils.username.UserNameUtil;
-import com.redhat.thermostat.utils.management.internal.ProcessUserInfoBuilder.ProcessUserInfo;
+import com.redhat.thermostat.common.portability.UserNameUtil;
 
 public class MXBeanConnectionPoolImpl implements MXBeanConnectionPoolControl, ThermostatIPCCallbacks {
 
@@ -94,7 +95,7 @@
     private boolean started;
 
     public MXBeanConnectionPoolImpl(File binPath, UserNameUtil userNameUtil, AgentIPCService ipcService) {
-        this(new ConnectorCreator(), binPath, new ProcessUserInfoBuilder(new ProcDataSource(), userNameUtil), 
+        this(new ConnectorCreator(), binPath, ProcessUserInfo.createBuilder(new ProcDataSource(), userNameUtil),
                 ipcService, new FileSystemUtils());
     }
 
--- a/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/ProcessUserInfoBuilder.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +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.utils.management.internal;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
-import com.redhat.thermostat.agent.utils.username.UserNameLookupException;
-import com.redhat.thermostat.agent.utils.username.UserNameUtil;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-
-/*
- * FIXME: This class was copied from system-backend to avoid adding new API.
- */
-class ProcessUserInfoBuilder {
-    
-    private static final ProcessUserInfo NON_EXISTENT_USER = new ProcessUserInfo();
-    private static final String PROC_STATUS_UID = "Uid:";
-    private static final Logger logger = LoggingUtils.getLogger(ProcessUserInfoBuilder.class);
-    private ProcDataSource source;
-    private UserNameUtil userNameUtil;
-    
-    ProcessUserInfoBuilder(ProcDataSource source, UserNameUtil userNameUtil) {
-        this.source = source;
-        this.userNameUtil = userNameUtil;
-    }
-    
-    static class ProcessUserInfo {
-        
-        private long uid;
-        private String username;
-        
-        ProcessUserInfo(long uid, String username) {
-            this.uid = uid;
-            this.username = username;
-        }
-        
-        ProcessUserInfo() {
-            this.uid = -1;
-            this.username = null;
-        }
-        
-        public long getUid() {
-            return uid;
-        }
-        
-        public String getUsername() {
-            return username;
-        }
-    }
-    
-    ProcessUserInfo build(int pid) {
-        ProcessUserInfo info = NON_EXISTENT_USER;
-        try {
-            Reader reader = source.getStatusReader(pid);
-            long uid = getUidFromProcfs(new BufferedReader(reader));
-            String name = null;
-            try {
-                name = userNameUtil.getUserName(uid);
-            } catch (UserNameLookupException e) {
-                logger.log(Level.WARNING, "Unable to retrieve username for uid: " + uid, e);
-            }
-            info = new ProcessUserInfo(uid, name);
-        } catch (IOException e) {
-            logger.log(Level.WARNING, "Unable to read user info for " + pid, e);
-        }
-        
-        return info;
-    }
-
-    /*
-     * Look for the following line:
-     * Uid:  <RealUid>   <EffectiveUid>   <SavedUid>   <FSUid>
-     */
-    private long getUidFromProcfs(BufferedReader br) throws IOException {
-        long uid = -1;
-        String line;
-        while ((line = br.readLine()) != null) {
-            line = line.trim();
-            if (line.startsWith(PROC_STATUS_UID)) {
-                String[] parts = line.split("\\s+");
-                if (parts.length == 5) {
-                    try {
-                        // Use Real UID
-                        uid = Long.parseLong(parts[1]);
-                    } catch (NumberFormatException e) {
-                        throw new IOException("Unexpected output from ps command", e);
-                    }
-                }
-                else {
-                    throw new IOException("Expected 5 parts from split /proc/${pid}/status output, got " + parts.length);
-                }
-            }
-        }
-        if (uid < 0) {
-            throw new IOException("Unable to determine UID from /proc/${pid}/status");
-        }
-        return uid;
-    }
-
-
-}
-
--- a/agent/core/src/main/java/com/redhat/thermostat/utils/username/internal/UserNameUtilImpl.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +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.utils.username.internal;
-
-import java.io.IOException;
-
-import com.redhat.thermostat.agent.utils.username.UserNameLookupException;
-import com.redhat.thermostat.agent.utils.username.UserNameUtil;
-import com.redhat.thermostat.shared.config.NativeLibraryResolver;
-
-public class UserNameUtilImpl implements UserNameUtil {
-    
-    static {
-        String lib = NativeLibraryResolver.getAbsoluteLibraryPath("UserNameUtilWrapper");
-        System.load(lib);
-    }
-    
-    public String getUserName(long uid) throws UserNameLookupException {
-        String username = null;
-        if (uid >= 0) {
-            try {
-                // getUserName0 may throw IOException. We catch it here and
-                // throw a more specific exception in order to avoid API 
-                // leakage. This exception is then dealt with in the caller of
-                // this method rather than here. This free's us from using the
-                // logger in a JNI class.
-                username = getUserName0(uid);
-            } catch (IOException e) {
-                throw new UserNameLookupException(e);
-            }
-        }
-        return username;
-    }
-    
-    private native String getUserName0(long uid) throws IOException;
-
-}
-
--- a/agent/core/src/main/native/HostName.c	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright 2012-2014 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.
- */
-
-#include "com_redhat_thermostat_agent_utils_hostname_HostName.h"
-
-#include <jni.h>
-#include <unistd.h>
-#include <string.h>
-
-#if !defined(_WIN32)
-# include <netdb.h>
-#else // windows
-# include <winsock2.h>
-#endif
-
-#ifndef NI_MAXHOST
-#define NI_MAXHOST 1025
-#endif /* NI_MAXHOST */
-
-JNIEXPORT jstring JNICALL
-Java_com_redhat_thermostat_agent_utils_hostname_HostName_getHostName
-  (JNIEnv *env, jclass HostNameClass)
-{
-    char hostname[NI_MAXHOST];
-    memset(hostname, 0, sizeof(hostname));
-
-    if (gethostname(hostname,  sizeof(hostname)) == 0) {
-        return (*env)->NewStringUTF(env, hostname);
-    }
-    return NULL;
-}
-
--- a/agent/core/src/main/native/UserNameUtilImpl.c	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/*
- * Copyright 2012-2014 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.
- */
-
-#include "com_redhat_thermostat_utils_username_internal_UserNameUtilImpl.h"
-
-#include <jni.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#if !defined(_WIN32)
-# include <pwd.h>
-#else // windows
-#endif
-
-static jint throw_IOException(JNIEnv *env, const char *message) {
-    const char *class_name = "java/io/IOException";
-    jclass class = (*env)->FindClass(env, class_name);
-    if (class == NULL) {
-        return -1;
-    }
-    return (*env)->ThrowNew(env, class, message);
-}
-
-#if !defined(_WIN32)
-
-JNIEXPORT jstring JNICALL
-Java_com_redhat_thermostat_utils_username_internal_UserNameUtilImpl_getUserName0
-    (JNIEnv *env, jclass ProcessUserInfoBuilderClass, jlong uid) {
-    size_t bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
-    if (bufsize < 0) {
-        throw_IOException(env, "Unable to retrieve recommended buffer size from sysconf");
-        return NULL;
-    }
-
-    char *buf = malloc(bufsize * sizeof(char));
-    if (!buf) {
-        throw_IOException(env, "Unable to allocate buffer for username");
-        return NULL;
-    }
-
-    struct passwd pwd;
-    struct passwd *ret;
-    int rc = getpwuid_r(uid, &pwd, buf, bufsize, &ret);
-    if (rc) {
-        // Error occurred
-        const char *error_message = strerror(rc);
-        throw_IOException(env, error_message);
-        free(buf);
-        return NULL;
-    }
-    if (!ret) {
-        // No username found
-        char err_buf[128]; // Large enough for even the largest UIDs
-        snprintf(err_buf, sizeof(err_buf), "Username not found for uid: %ld", uid);
-        throw_IOException(env, err_buf);
-        free(buf);
-        return NULL;
-    }
-
-    jstring name = (*env)->NewStringUTF(env, pwd.pw_name);
-    free(buf);
-    return name;
-}
-
-#else // Windows
-JNIEXPORT jstring JNICALL
-Java_com_redhat_thermostat_utils_username_internal_UserNameUtilImpl_getUserName0
-    (JNIEnv *env, jclass ProcessUserInfoBuilderClass, jlong uid) {
-
-    // TODO
-    throw_IOException(env, "UserNameUtilImpl.getUserName() no yet implemented on Windows");
-    jstring name = (*env)->NewStringUTF(env, "xxxuserxxx");
-    return name;
-}
-#endif
-
-
--- a/agent/core/src/main/native/WindowsHelperImpl.c	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,350 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-#include "com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl.h"
-#include <jni.h>
-#include <unistd.h>
-#include <string.h>
-
-#if !defined(_WIN32)
-# include <netdb.h>
-#else // windows
-# include <winsock2.h>
-# include <psapi.h>
-#endif
-
-#ifndef NI_MAXHOST
-#define NI_MAXHOST 1025
-#endif /* NI_MAXHOST */
-
-#if defined(NDEBUG)
-static void testLength(JNIEnv* env, jlongArray array, minLength) {}
-#else
-static void testLength(JNIEnv* env, jlongArray array, minLength) {
-    // sanity test
-    jsize len = (*env)->GetArrayLength(env, array);
-    assert(len >= minLength);
-}
-#endif
-
-/*
- * Class:     com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl
- * Method:    getHostName0
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL
-Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getHostName0
-  (JNIEnv *env, jclass winHelperClass, jboolean prependDomain)
-{
-      char hostname[NI_MAXHOST];
-      memset(hostname, 0, sizeof(hostname));
-
-      if (gethostname(hostname,  sizeof(hostname)) == 0) {
-          return (*env)->NewStringUTF(env, hostname);
-      }
-      return NULL;
-}
-
-/*
- * Class:     com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl
- * Method:    getOSVersion0
- * Signature: ([J)V
- */
-JNIEXPORT void JNICALL Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getOSVersion0
-  (JNIEnv *env, jclass winHelperClass, jlongArray array)
-{
-    testLength(env, array, 3);
-
-    // Get the element pointer
-    jlong* data = (*env)->GetLongArrayElements(env, array, 0);
-
-    OSVERSIONINFOEX vinfo;
-    vinfo.dwOSVersionInfoSize = sizeof(vinfo);
-    GetVersionEx(&vinfo);
-    data[0] = vinfo.dwMajorVersion;
-    data[1] = vinfo.dwMinorVersion;
-    data[2] = vinfo.dwBuildNumber;
-
-    (*env)->ReleaseLongArrayElements(env, array, data, 0);
-}
-
-
-/*
- * Class:     com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl
- * Method:    getUid0
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL
-Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getUid0
-  (JNIEnv *env, jclass winHelperClass, jint pid)
-{
-    // TODO - implement this stub
-    return 987654321;
-}
-
-/*
- * Class:     com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl
- * Method:    getUserName0
- * Signature: (I)Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL
-Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getUserName0
-  (JNIEnv *env, jclass winHelperClass, jint pid, jboolean prependDomain)
-{
-    // TODO - implement this stub
-    return (*env)->NewStringUTF(env, "(unavailable)");
-}
-
-/*
- * Class:     com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl
- * Method:    getEnvironment0
- * Signature: ()[Ljava/lang/String;
- */
-JNIEXPORT jobjectArray JNICALL
-Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getEnvironment0
-  (JNIEnv *env, jclass winHelperClass, jint pid)
-{
-    // TODO - implement this stub
-    jobjectArray ret = (jobjectArray)(*env)->NewObjectArray(env, 0, (*env)->FindClass(env, "java/lang/String"), (*env)->NewStringUTF(env, ""));
-    return ret;
-}
-
-
-/*
- * Class:     com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl
- * Method:    getGlobalMemoryStatus0
- * Signature: ([J)V
- */
-JNIEXPORT boolean JNICALL Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getGlobalMemoryStatus0
-  (JNIEnv *env, jclass winHelperClass, jlongArray array)
-{
-    testLength(env, array, 8);
-
-    // Get the element pointer
-    jlong* data = (*env)->GetLongArrayElements(env, array, 0);
-
-    // get the memory info
-    MEMORYSTATUSEX statex;
-    statex.dwLength = sizeof(statex);
-    GlobalMemoryStatusEx(&statex);
-    data[0] = statex.dwMemoryLoad;
-    data[1] = statex.ullTotalPhys;
-    data[2] = statex.ullAvailPhys;
-    data[3] = statex.ullTotalPageFile;
-    data[4] = statex.ullAvailPageFile;
-    data[5] = statex.ullTotalVirtual;
-    data[6] = statex.ullAvailVirtual;
-    data[7] = statex.ullAvailExtendedVirtual;
-
-    (*env)->ReleaseLongArrayElements(env, array, data, 0);
-    return TRUE;
-}
-
-/*
- * Class:     com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl
- * Method:    getPerformanceInfo0
- * Signature: ([J)V
- */
-JNIEXPORT boolean JNICALL Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getPerformanceInfo0
-  (JNIEnv *env, jclass winHelperClass, jlongArray array)
-{
-    testLength(env, array, 13);
-
-    // Get the element pointer
-    jlong* data = (*env)->GetLongArrayElements(env, array, 0);
-
-    /**
-     // from PERFORMANCE_INFORMATION (13 values)
-        SIZE_T CommitTotal;
-        SIZE_T CommitLimit;
-        SIZE_T CommitPeak;
-        SIZE_T PhysicalTotal;
-        SIZE_T PhysicalAvailable;
-        SIZE_T SystemCache;
-        SIZE_T KernelTotal;
-        SIZE_T KernelPaged;
-        SIZE_T KernelNonpaged;
-        SIZE_T PageSize;
-        DWORD  HandleCount;
-        DWORD  ProcessCount;
-        DWORD  ThreadCount;
-     */
-
-    // get the memeory info
-    PERFORMANCE_INFORMATION statex;
-    statex.cb = sizeof(statex);
-    GetPerformanceInfo(&statex, statex.cb);
-    data[0] = statex.CommitTotal;
-    data[1] = statex.CommitLimit;
-    data[2] = statex.CommitPeak;
-    data[3] = statex.PhysicalTotal;
-    data[4] = statex.PhysicalAvailable;
-    data[5] = statex.SystemCache;
-    data[6] = statex.KernelTotal;
-    data[7] = statex.KernelPaged;
-    data[8] = statex.KernelNonpaged;
-    data[9] = statex.PageSize;
-    data[10] = statex.HandleCount;
-    data[11] = statex.ProcessCount;
-    data[12] = statex.ThreadCount;
-
-    (*env)->ReleaseLongArrayElements(env, array, data, 0);
-    return TRUE;
-}
-
-static unsigned __int64 convertFileTimeToInt64( const FILETIME * pFileTime )
-{
-  ULARGE_INTEGER largeInt;
-
-  largeInt.LowPart = pFileTime->dwLowDateTime;
-  largeInt.HighPart = pFileTime->dwHighDateTime;
-
-  return largeInt.QuadPart;
-}
-
-/*
- * Class:     com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl
- * Method:    getProcessMemoryInfo0
- * Signature: (I[J)V
- */
-JNIEXPORT jboolean JNICALL Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getProcessInfo0
-  (JNIEnv *env, jclass winHelperClass, jint pid, jlongArray array)
-{
-    testLength(env, array, 4);
-
-    // Get the element pointer
-    jlong* data = (*env)->GetLongArrayElements(env, array, 0);
-
-    HANDLE hProcess;
-    PROCESS_MEMORY_COUNTERS pmc;
-
-    hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid );
-    if (NULL == hProcess)
-        return FALSE;
-
-    pmc.cb = sizeof(pmc);
-    if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) ) {
-        data[0] = pmc.WorkingSetSize;
-    }
-    else {
-        (*env)->ReleaseLongArrayElements(env, array, data, 0);
-        return FALSE;
-    }
-
-    FILETIME creationTime;
-    FILETIME exitTime;
-    FILETIME kernelTime;
-    FILETIME userTime;
-
-    if ( GetProcessTimes( hProcess, &creationTime, &exitTime, &kernelTime, &userTime ) ) {
-        data[1] = convertFileTimeToInt64(&userTime);
-        data[2] = convertFileTimeToInt64(&kernelTime);
-    }
-
-    CloseHandle(hProcess);
-
-    (*env)->ReleaseLongArrayElements(env, array, data, 0);
-    return TRUE;
-}
-
-/*
- * Class:     com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl
- * Method:    getCPUString0
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getCPUString0
-  (JNIEnv *env, jclass winHelperClass)
-{
-    // Get extended ids.
-    int CPUInfo[4] = {-1};
-    __cpuid(CPUInfo, 0x80000000);
-    unsigned int nExIds = CPUInfo[0];
-
-    // Get the information associated with each extended ID.
-    char CPUBrandString[0x40] = { 0 };
-    for( unsigned int i=0x80000000; i<=nExIds; ++i)
-    {
-        __cpuid(CPUInfo, i);
-
-        // Interpret CPU brand string and cache information.
-        if  (i == 0x80000002)
-        {
-            memcpy( CPUBrandString,
-            CPUInfo,
-            sizeof(CPUInfo));
-        }
-        else if( i == 0x80000003 )
-        {
-            memcpy( CPUBrandString + 16,
-            CPUInfo,
-            sizeof(CPUInfo));
-        }
-        else if( i == 0x80000004 )
-        {
-            memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
-        }
-    }
-    return (*env)->NewStringUTF(env, CPUBrandString);
-
-}
-
-/*
- * Class:     com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl
- * Method:    getCPUCount0
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getCPUCount0
-  (JNIEnv *env, jclass winHelperClass)
-{
-    SYSTEM_INFO sysinfo;
-    GetSystemInfo(&sysinfo);
-
-    return sysinfo.dwNumberOfProcessors;
-}
-
-/*
- * Class:     com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl
- * Method:    getClockTicksPerSecond0
- * Signature: ()I
- */
-JNIEXPORT jlong JNICALL Java_com_redhat_thermostat_agent_utils_windows_WindowsHelperImpl_getClockTicksPerSecond0
-  (JNIEnv *env, jclass winHelperClass)
-{
-    LARGE_INTEGER freq;
-    QueryPerformanceFrequency(&freq);
-
-    return (jlong)(freq.QuadPart);
-}
--- a/agent/core/src/test/java/com/redhat/thermostat/agent/internal/ActivatorTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/agent/core/src/test/java/com/redhat/thermostat/agent/internal/ActivatorTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -44,6 +44,7 @@
 
 import java.io.File;
 
+import com.redhat.thermostat.common.portability.UserNameUtil;
 import org.junit.Before;
 import org.junit.Test;
 import org.osgi.framework.ServiceRegistration;
@@ -51,13 +52,11 @@
 import com.redhat.thermostat.agent.VmBlacklist;
 import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
 import com.redhat.thermostat.agent.utils.management.MXBeanConnectionPool;
-import com.redhat.thermostat.agent.utils.username.UserNameUtil;
 import com.redhat.thermostat.shared.config.CommonPaths;
 import com.redhat.thermostat.shared.config.NativeLibraryResolver;
 import com.redhat.thermostat.testutils.StubBundleContext;
 import com.redhat.thermostat.utils.management.internal.MXBeanConnectionPoolControl;
 import com.redhat.thermostat.utils.management.internal.MXBeanConnectionPoolImpl;
-import com.redhat.thermostat.utils.username.internal.UserNameUtilImpl;
 
 public class ActivatorTest {
     
@@ -73,6 +72,11 @@
     
         context = new StubBundleContext();
         context.registerService(CommonPaths.class.getName(), paths, null);
+
+        // required by MXBeanConnectionPoolImpl
+        UserNameUtil userNameUtil = mock(UserNameUtil.class);
+        context.registerService(UserNameUtil.class.getName(), userNameUtil, null);
+
         AgentIPCService ipcService = mock(AgentIPCService.class);
         ipcReg = context.registerService(AgentIPCService.class.getName(), ipcService, null);
     }
@@ -84,7 +88,6 @@
 
         assertTrue(context.isServiceRegistered(MXBeanConnectionPool.class.getName(), MXBeanConnectionPoolImpl.class));
         assertTrue(context.isServiceRegistered(MXBeanConnectionPoolControl.class.getName(), MXBeanConnectionPoolImpl.class));
-        assertTrue(context.isServiceRegistered(UserNameUtil.class.getName(), UserNameUtilImpl.class));
         assertTrue(context.isServiceRegistered(VmBlacklist.class.getName(), VmBlacklistImpl.class));
     }
 
--- a/agent/core/src/test/java/com/redhat/thermostat/agent/utils/ProcessCheckerTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +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.agent.utils;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.File;
-
-import org.junit.Test;
-
-public class ProcessCheckerTest {
-
-    private static final int SOME_PID = 80980;
-    
-    @Test
-    public void testProcessExists() {
-        basicTest(true);
-    }
-    
-    @Test
-    public void testProcessNotExisting() {
-        basicTest(false);
-    }
-    
-    private void basicTest(boolean expected) {
-        final File baseFile = mock(File.class);
-        when(baseFile.exists()).thenReturn(expected);
-        ProcessChecker process = new ProcessChecker() {
-            @Override
-            File mapToFile(int pid) {
-                assertEquals(SOME_PID, pid);
-                return baseFile;
-            }
-        };
-        assertEquals(expected, process.exists(SOME_PID));
-    }
-}
--- a/agent/core/src/test/java/com/redhat/thermostat/agent/utils/SysConfTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +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.agent.utils;
-
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
-public class SysConfTest {
-
-    @Test
-    public void test() {
-        long ticksPerSecond = SysConf.getClockTicksPerSecond();
-        assertTrue(ticksPerSecond >= 1);
-    }
-}
-
--- a/agent/core/src/test/java/com/redhat/thermostat/agent/utils/linux/ProcDataSourceTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +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.agent.utils.linux;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.Reader;
-
-import com.redhat.thermostat.shared.config.OS;
-import org.junit.Assume;
-import org.junit.Test;
-
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
-import com.redhat.thermostat.testutils.TestUtils;
-
-public class ProcDataSourceTest {
-
-    @Test
-    public void testGetCpuInfoReader() throws IOException {
-        Assume.assumeTrue(OS.IS_UNIX);
-        Reader r = new ProcDataSource().getCpuInfoReader();
-        assertNotNull(r);
-    }
-
-    @Test
-    public void testGetCpuLoadReader() throws IOException {
-        Assume.assumeTrue(OS.IS_UNIX);
-        Reader r = new ProcDataSource().getCpuLoadReader();
-        assertNotNull(r);
-    }
-
-    @Test
-    public void testGetMemInfoReader() throws IOException {
-        Assume.assumeTrue(OS.IS_UNIX);
-        Reader r = new ProcDataSource().getMemInfoReader();
-        assertNotNull(r);
-    }
-
-    @Test
-    public void testGetStatReader() throws IOException {
-        Assume.assumeTrue(OS.IS_UNIX);
-        int pid = TestUtils.getProcessId();
-        Reader r = new ProcDataSource().getStatReader(pid);
-        assertNotNull(r);
-    }
-
-    @Test
-    public void testGetEnvironReader() throws IOException {
-        Assume.assumeTrue(OS.IS_UNIX);
-        int pid = TestUtils.getProcessId();
-        Reader r = new ProcDataSource().getEnvironReader(pid);
-        assertNotNull(r);
-    }
-
-    @Test
-    public void testIoReader() throws Exception {
-        Assume.assumeTrue(OS.IS_UNIX);
-        int pid = TestUtils.getProcessId();
-        Reader r = new ProcDataSource().getIoReader(pid);
-        assertNotNull(r);
-    }
-
-    @Test
-    public void testStatReader() throws Exception {
-        Assume.assumeTrue(OS.IS_UNIX);
-        int pid = TestUtils.getProcessId();
-        Reader r = new ProcDataSource().getStatReader(pid);
-        assertNotNull(r);
-    }
-
-    @Test
-    public void testStatusReader() throws Exception {
-        Assume.assumeTrue(OS.IS_UNIX);
-        int pid = TestUtils.getProcessId();
-        Reader r = new ProcDataSource().getStatusReader(pid);
-        assertNotNull(r);
-    }
-}
-
--- a/agent/core/src/test/java/com/redhat/thermostat/agent/utils/windows/WindowsHelperImplTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +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.agent.utils.windows;
-
-import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl;
-import com.redhat.thermostat.shared.config.OS;
-
-import org.junit.Assume;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import java.util.Map;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-/**
- * These tests are disabled until we get the DLL path issues sorted out
- * TODO - These tests currently fail on Windows because the helper DLL isn't on the execution path
- */
-
-@Ignore
-public class WindowsHelperImplTest {
-
-    @Test
-    public void loadNativeLib() {
-        Assume.assumeTrue(OS.IS_WINDOWS);
-        final WindowsHelperImpl impl = WindowsHelperImpl.INSTANCE;
-        assertNotNull(impl);
-    }
-
-    @Test
-    public void testGetHostInfo() {
-        Assume.assumeTrue(OS.IS_WINDOWS);
-        final WindowsHelperImpl impl = WindowsHelperImpl.INSTANCE;
-        assertNotNull(impl);
-        assertContainsData(impl.getHostName());
-        assertContainsData(impl.getOSName());
-        assertTrue(impl.getOSName().toLowerCase().contains("win"));
-        assertContainsData(impl.getOSVersion());
-        assertContainsData(impl.getCPUModel());
-        assertTrue(impl.getCPUCount() > 0);
-        assertTrue(impl.getTotalMemory() > 0);
-    }
-
-    @Test
-    @Ignore
-    public void testGetProcessInfo() {
-        Assume.assumeTrue(OS.IS_WINDOWS);
-        final WindowsHelperImpl impl = WindowsHelperImpl.INSTANCE;
-        assertNotNull(impl);
-        int pid = /*TODO: retrieve current process identifier*/0;
-        assertContainsData(impl.getUserName(pid));
-        assertTrue(impl.getUid(pid) >= 0);
-        Map<String,String> envMap = impl.getEnvironment(pid);
-        assertNotNull(envMap);
-        assertFalse(envMap.isEmpty());
-    }
-
-    private static void assertContainsData( final String s ) {
-        assertNotNull(s);
-        assertFalse(s.isEmpty());
-    }
-}
--- a/agent/core/src/test/java/com/redhat/thermostat/backend/internal/VmMonitorTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/agent/core/src/test/java/com/redhat/thermostat/backend/internal/VmMonitorTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -58,7 +58,7 @@
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
-import com.redhat.thermostat.agent.utils.ProcessChecker;
+import com.redhat.thermostat.common.portability.ProcessChecker;
 import com.redhat.thermostat.backend.VmUpdateListener;
 
 import sun.jvmstat.monitor.HostIdentifier;
--- a/agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImplTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImplTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -53,6 +53,8 @@
 import java.nio.file.attribute.UserPrincipal;
 import java.nio.file.attribute.UserPrincipalLookupService;
 
+import com.redhat.thermostat.common.portability.ProcessUserInfo;
+import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
@@ -67,7 +69,6 @@
 import com.redhat.thermostat.agent.utils.management.MXBeanConnectionException;
 import com.redhat.thermostat.utils.management.internal.MXBeanConnectionPoolImpl.ConnectorCreator;
 import com.redhat.thermostat.utils.management.internal.MXBeanConnectionPoolImpl.FileSystemUtils;
-import com.redhat.thermostat.utils.management.internal.ProcessUserInfoBuilder.ProcessUserInfo;
 
 public class MXBeanConnectionPoolImplTest {
     
--- a/agent/ipc/server/pom.xml	Fri Jan 20 10:48:09 2017 -0500
+++ b/agent/ipc/server/pom.xml	Mon Jan 23 10:11:31 2017 -0500
@@ -91,6 +91,11 @@
       <version>${project.version}</version>
       <scope>test</scope>
     </dependency>
+      <dependency>
+          <groupId>com.redhat.thermostat</groupId>
+          <artifactId>thermostat-common-portability</artifactId>
+          <version>1.99.12-SNAPSHOT</version>
+      </dependency>
   </dependencies>
 
   <build>
--- a/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/IPCConfigurationWriter.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/agent/ipc/server/src/main/java/com/redhat/thermostat/agent/ipc/server/internal/IPCConfigurationWriter.java	Mon Jan 23 10:11:31 2017 -0500
@@ -43,14 +43,13 @@
 import java.util.Properties;
 
 import com.redhat.thermostat.agent.ipc.common.internal.IPCType;
+import com.redhat.thermostat.common.portability.PortableProcessImpl;
 import com.redhat.thermostat.shared.config.OS;
 
 class IPCConfigurationWriter {
 
     static final String PROP_IPC_TYPE = "type";
     private static final String PROP_UNIX_SOCKET_DIR = "unixsocket.dir";
-
-
     private static final String PROP_TCP_SOCKET_SUFFIX= ".tcpsocket.port";
     //private static final String TCP_SOCKET_JUMBO_FRAMES = "tcpsocket.jumboframes";
 
@@ -96,17 +95,25 @@
         props.setProperty(PROP_IPC_TYPE, OS.IS_UNIX ? IPCType.UNIX_SOCKET.getConfigValue() : IPCType.TCP_SOCKET.getConfigValue());
 
         // unix socket will work without configuration (creates sockets in tmp directory
-        // but tcpsocket always needs ports (in the future, should support service discovery)
+        // but tcpsocket always needs ports predefined (in the future, should support service discovery)
 
         // this implementation is flawed;
         //    the unused ports might be in used by a process that simply wasn't running at thermostat setup time.
 
         {
-            int cmdPort = findUnusedTCPSocket(TEST_SOCKET_LOW,TEST_SOCKET_HIGH);
-            int aport = cmdPort == 0 ? 0 : findUnusedTCPSocket(cmdPort+1,TEST_SOCKET_HIGH);
+            int cmdPort = findUnusedTCPSocket(TEST_SOCKET_LOW, TEST_SOCKET_HIGH);
+            int aport = cmdPort == 0 ? 0 : findUnusedTCPSocket(cmdPort + 1, TEST_SOCKET_HIGH);
 
             props.setProperty("command-channel" + PROP_TCP_SOCKET_SUFFIX, Integer.toString(cmdPort));
             props.setProperty("agent-proxy" + PROP_TCP_SOCKET_SUFFIX, Integer.toString(aport));
+
+            // write a property for each user on the system - currently only the current user
+            // note: this is required for UNIX too
+            if (OS.IS_WINDOWS) {
+                int uport = aport == 0 ? 0 : findUnusedTCPSocket( aport + 1, TEST_SOCKET_HIGH);
+                int uid = PortableProcessImpl.INSTANCE.getUid(0); // if pid=0, gets uid of current process
+                props.setProperty("agent-proxy-" + uid + PROP_TCP_SOCKET_SUFFIX, Integer.toString(uport));
+            }
         }
 
         try (FileOutputStream fos = helper.createStream(configFile)) {
--- a/common/pom.xml	Fri Jan 20 10:48:09 2017 -0500
+++ b/common/pom.xml	Mon Jan 23 10:11:31 2017 -0500
@@ -67,6 +67,7 @@
   <modules>
     <module>core</module>
     <module>command</module>
+    <module>portability</module>
     <module>test</module>
   </modules>
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/Makefile	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,86 @@
+CC         = gcc
+JAVAH      = javah
+MYCFLAGS   = -c -Wall $(EXTRA_CFLAGS)
+MYLDFLAGS  = -shared $(EXTRA_CFLAGS)
+COPY       = cp -a
+
+CLASSPATH  = target/classes/
+TARGET_DIR = target
+
+ifeq ($(OS),Windows_NT)
+    JNI_PLATFORM = win32
+    SO_PREFIX  =
+    SO_SUFFIX  = .dll
+else
+    JNI_PLATFORM = linux
+    SO_PREFIX  = lib
+    SO_SUFFIX  = .so
+    MYCFLAGS   += -fPIC
+    MYLDFLAGS  += -fPIC
+endif
+
+INCLUDE    = -I $(TARGET_DIR) -I "$(JAVA_HOME)/include/" -I "$(JAVA_HOME)/include/$(JNI_PLATFORM)"
+
+HOSTNAME_SOURCES    = src/main/native/HostName.c
+HOSTNAME_TARGET     = $(TARGET_DIR)/HostName.c
+HOSTNAME_OBJECTS    = $(HOSTNAME_TARGET:.c=.o)
+HOSTNAME_EXECUTABLE = $(SO_PREFIX)HostNameWrapper$(SO_SUFFIX)
+
+USERNAME_SOURCES    = src/main/native/UserNameUtilImpl.c
+USERNAME_TARGET     = $(TARGET_DIR)/UserNameUtilImpl.c
+USERNAME_OBJECTS    = $(USERNAME_TARGET:.c=.o)
+USERNAME_EXECUTABLE = $(SO_PREFIX)UserNameUtilWrapper$(SO_SUFFIX)
+
+WINHELPER_SOURCES    = src/main/native/WindowsHelperImpl.c
+WINHELPER_TARGET     = $(TARGET_DIR)/WindowsHelperImpl.c
+WINHELPER_OBJECTS    = $(WINHELPER_TARGET:.c=.o)
+WINHELPER_EXECUTABLE = $(SO_PREFIX)WindowsHelperWrapper$(SO_SUFFIX)
+
+EXECUTABLES          = $(HOSTNAME_EXECUTABLE) $(USERNAME_EXECUTABLE)
+
+.PHONY:UserNameUtilImpl
+JNI_LIST = com.redhat.thermostat.common.portability.HostName com.redhat.thermostat.common.portability.internal.linux.UserNameUtilImpl
+
+ifeq ($(OS),Windows_NT)
+    EXECUTABLES  += $(WINHELPER_EXECUTABLE)
+    JNI_LIST     +=  com.redhat.thermostat.common.portability.internal.windows.WindowsHelperImpl
+endif
+
+$(JNI_LIST):
+	$(JAVAH) -force -classpath $(CLASSPATH) -d $(TARGET_DIR) $(JNI_LIST)
+
+all: $(JNI_LIST) init $(HOSTNAME_SOURCES) $(USERNAME_SOURCES) $(WINHELPER_SOURCES) $(EXECUTABLES)
+
+.PHONY:
+init:
+	$(COPY) $(HOSTNAME_SOURCES) $(HOSTNAME_TARGET)
+	$(COPY) $(USERNAME_SOURCES) $(USERNAME_TARGET)
+	$(COPY) $(WINHELPER_SOURCES) $(WINHELPER_TARGET)
+
+$(HOSTNAME_EXECUTABLE): $(HOSTNAME_OBJECTS)
+	$(CC) $(MYLDFLAGS) $(LDFLAGS) $(HOSTNAME_OBJECTS) $(PLATFORM_LIBS) -o $(TARGET_DIR)/$@
+
+$(USERNAME_EXECUTABLE): $(USERNAME_OBJECTS)
+	$(CC) $(MYLDFLAGS) $(LDFLAGS) $(USERNAME_OBJECTS) $(PLATFORM_LIBS) -o $(TARGET_DIR)/$@
+
+$(WINHELPER_EXECUTABLE): $(WINHELPER_OBJECTS)
+	$(CC) $(MYLDFLAGS) $(LDFLAGS) $(WINHELPER_OBJECTS) $(PLATFORM_LIBS) -l psapi -o $(TARGET_DIR)/$@
+
+.c.o:
+	$(CC) $(MYCFLAGS) $(CFLAGS) $(INCLUDE) $< -o $@
+
+.cpp.o:
+	$(CC) $(MYCFLAGS) $(CFLAGS) $(INCLUDE) $< -o $@
+
+clean-lib:
+	rm -f $(TARGET_DIR)/$(HOSTNAME_EXECUTABLE)
+	rm -f $(TARGET_DIR)/$(USERNAME_EXECUTABLE)
+	rm -f $(TARGET_DIR)/$(WINHELPER_EXECUTABLE)
+
+clean-obj:
+	rm -f $(HOSTNAME_OBJECTS) $(HOSTNAME_TARGET)
+	rm -f $(USERNAME_OBJECTS) $(USERNAME_TARGET)
+	rm -f $(WINHELPER_OBJECTS) $(WINHELPER_TARGET)
+
+clean: clean-obj clean-lib
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/pom.xml	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,223 @@
+<?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>
+        <groupId>com.redhat.thermostat</groupId>
+        <artifactId>thermostat-common</artifactId>
+        <version>1.99.12-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>thermostat-common-portability</artifactId>
+    <packaging>bundle</packaging>
+
+    <name>Thermostat Common Portability Code</name>
+
+    <profiles>
+        <profile>
+            <id>default</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+        </profile>
+
+        <profile>
+            <id>linux</id>
+            <activation>
+                <os><family>Unix</family></os>
+            </activation>
+            <properties>
+                <platform.libs/>
+            </properties>
+        </profile>
+
+        <profile>
+            <id>windows</id>
+            <activation>
+                <os><family>Windows</family></os>
+            </activation>
+            <properties>
+                <platform.libs>-lws2_32</platform.libs>
+                <sharedlib.prefix/>
+                <sharedlib.suffix>.dll</sharedlib.suffix>
+            </properties>
+        </profile>
+    </profiles>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.redhat.thermostat</groupId>
+            <artifactId>thermostat-annotations</artifactId>
+            <version>${project.version}</version>
+            <!--scope>test</scope-->
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </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-common-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.redhat.thermostat</groupId>
+            <artifactId>thermostat-shared-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+    </dependencies>
+
+    <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.common.portability</Bundle-SymbolicName>
+                        <Bundle-Activator>com.redhat.thermostat.common.portability.internal.Activator</Bundle-Activator>
+                        <Export-Package>
+                            com.redhat.thermostat.common.portability,
+                            com.redhat.thermostat.common.portability.linux
+                        </Export-Package>
+                        <Private-Package>
+                            com.redhat.thermostat.common.portability.internal,
+                            com.redhat.thermostat.common.portability.internal.linux,
+                            com.redhat.thermostat.common.portability.internal.windows
+                        </Private-Package>
+                        <!-- Do not autogenerate uses clauses in Manifests -->
+                        <_nouses>true</_nouses>
+                    </instructions>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <systemPropertyVariables>
+                        <com.redhat.thermostat.shared.loader.testNativesHome>${project.build.directory}</com.redhat.thermostat.shared.loader.testNativesHome>
+                    </systemPropertyVariables>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>compile</phase>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <executable>make</executable>
+                    <arguments>
+                        <argument>all</argument>
+                        <argument>CC=${c.compiler}</argument>
+                        <argument>SO_PREFIX=${sharedlib.prefix}</argument>
+                        <argument>SO_SUFFIX=${sharedlib.suffix}</argument>
+                        <argument>EXTRA_CFLAGS=${cflags}</argument>
+                        <argument>JNI_PLATFORM=${jni.platform}</argument>
+                        <argument>PLATFORM_LIBS=${platform.libs}</argument>
+                    </arguments>
+                    <systemProperties>
+                        <systemProperty>
+                            <key>JAVA_HOME</key>
+                            <value>${java.home}</value>
+                        </systemProperty>
+                    </systemProperties>
+                </configuration>
+            </plugin>
+        </plugins>
+
+        <pluginManagement>
+            <plugins>
+                <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+                <plugin>
+                    <groupId>org.eclipse.m2e</groupId>
+                    <artifactId>lifecycle-mapping</artifactId>
+                    <configuration>
+                        <lifecycleMappingMetadata>
+                            <pluginExecutions>
+                                <pluginExecution>
+                                    <pluginExecutionFilter>
+                                        <groupId>org.codehaus.mojo</groupId>
+                                        <artifactId>exec-maven-plugin</artifactId>
+                                        <versionRange>[1.2.1,)</versionRange>
+                                        <goals>
+                                            <goal>exec</goal>
+                                        </goals>
+                                    </pluginExecutionFilter>
+                                    <action>
+                                        <ignore/>
+                                    </action>
+                                </pluginExecution>
+                            </pluginExecutions>
+                        </lifecycleMappingMetadata>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+
+</project>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/HostName.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,57 @@
+/*
+ * 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.common.portability;
+
+import com.redhat.thermostat.shared.config.NativeLibraryResolver;
+
+/**
+ * Finds the current host name without doing a DNS lookup
+ */
+public class HostName {
+
+    static {
+        String lib = NativeLibraryResolver.getAbsoluteLibraryPath("HostNameWrapper");
+        System.load(lib);
+    }
+    
+    public static String getLocalHostName() {
+        return getHostName();
+    }
+    
+    private static native String getHostName();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableHost.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,56 @@
+/*
+ * 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.common.portability;
+
+public interface PortableHost {
+
+    String getHostName();
+
+    String getOSName();
+
+    String getOSVersion();
+
+    String getCPUModel();
+
+    int getCPUCount();
+
+    long getTotalMemory();
+
+    long getClockTicksPerSecond();
+
+    PortableMemoryStat getMemoryStat();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableHostImpl.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,46 @@
+/*
+ * 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.common.portability;
+
+import com.redhat.thermostat.common.portability.internal.windows.WindowsHostImpl;
+import com.redhat.thermostat.shared.config.OS;
+
+public class PortableHostImpl {
+
+    public static final PortableHost INSTANCE = OS.IS_WINDOWS ? WindowsHostImpl.INSTANCE : null;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableMemoryStat.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,89 @@
+/*
+ * 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.common.portability;
+
+public class PortableMemoryStat {
+
+    private final long timeStamp;
+    private final long total;
+    private final long free;
+    private final long buffers;
+    private final long cached;
+    private final long swapTotal;
+    private final long swapFree;
+    private final long commitLimit;
+
+    public PortableMemoryStat(long timeStamp, long total, long free, long buffers, long cached, long swapTotal, long swapFree, long commitLimit) {
+        this.timeStamp = timeStamp;
+        this.total = total;
+        this.free = free;
+        this.buffers = buffers;
+        this.cached = cached;
+        this.swapTotal = swapTotal;
+        this.swapFree = swapFree;
+        this.commitLimit = commitLimit;
+    }
+
+    public long getTimeStamp() {
+        return timeStamp;
+    }
+    public long getTotal() {
+        return total;
+    }
+    public long getFree() {
+        return free;
+    }
+    public long getBuffers() {
+        return buffers;
+    }
+    public long getCached() {
+        return cached;
+    }
+    public long getSwapTotal() {
+        return swapTotal;
+    }
+    public long getSwapFree() {
+        return swapFree;
+    }
+    public long getCommitLimit() {
+        return commitLimit;
+    }
+
+    public static PortableMemoryStat build() {
+        return PortableHostImpl.INSTANCE.getMemoryStat();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcess.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,62 @@
+/*
+ * 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.common.portability;
+
+import com.redhat.thermostat.common.Clock;
+
+import java.util.Map;
+
+public interface PortableProcess {
+
+    boolean exists(int pid);
+
+    String getUserName(int pid);
+
+    int getUid(int pid);
+
+    Map<String, String> getEnvironment(int pid);
+
+    PortableProcessStat getProcessStat(int pid);
+
+    PortableVmIoStat getVmIoStat(Clock clock, int pid);
+
+    boolean terminateProcess(int pid);
+
+    boolean terminateProcess(int pid, boolean wait);
+
+    boolean terminateProcess(int pid, int exitcode, int waitMillis);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcessImpl.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,46 @@
+/*
+ * 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.common.portability;
+
+import com.redhat.thermostat.common.portability.internal.linux.LinuxProcessImpl;
+import com.redhat.thermostat.common.portability.internal.windows.WindowsHelperImpl;
+import com.redhat.thermostat.common.portability.internal.windows.WindowsProcessImpl;
+import com.redhat.thermostat.shared.config.OS;
+
+public final class PortableProcessImpl {
+    public static final PortableProcess INSTANCE = OS.IS_WINDOWS ? WindowsProcessImpl.INSTANCE : LinuxProcessImpl.INSTANCE;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcessStat.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,77 @@
+/*
+ * 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.common.portability;
+
+public class PortableProcessStat {
+
+    /* All times are measured in clock ticks */
+
+    private final int pid;
+    private final long userTime;
+    private final long kernelTime;
+
+    public PortableProcessStat(int pid, long userTime, long kernelTime) {
+        this.pid = pid;
+        this.userTime = userTime;
+        this.kernelTime = kernelTime;
+    }
+
+    public int getPid() {
+        return pid;
+    }
+
+    /**
+     * @return the time this process has spent in user-mode as a number of
+     * kernel ticks
+     */
+    public long getUserTime() {
+        return userTime;
+    }
+
+    /**
+     * @return the time this process spent in kernel-mode as a number of kernel
+     * ticks
+     */
+    public long getKernelTime() {
+        return kernelTime;
+    }
+
+    public static PortableProcessStat build(int pid) {
+        return PortableProcessImpl.INSTANCE.getProcessStat(pid);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableVmIoStat.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,81 @@
+/*
+ * 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.common.portability;
+
+import com.redhat.thermostat.common.Clock;
+
+public class PortableVmIoStat {
+
+    private final long timeStamp;
+
+    private final long readSyscalls;
+    private final long writeSyscalls;
+    private final long charactersRead;
+    private final long charactersWritten;
+
+    public PortableVmIoStat(final long timeStamp, final long readSyscalls, final long writeSyscalls, final long charactersRead, final long charactersWritten) {
+        this.timeStamp = timeStamp;
+        this.readSyscalls = readSyscalls;
+        this.writeSyscalls = writeSyscalls;
+        this.charactersRead = charactersRead;
+        this.charactersWritten = charactersWritten;
+    }
+
+    public static PortableVmIoStat build(Clock clock, int pid) {
+        return PortableProcessImpl.INSTANCE.getVmIoStat(clock, pid);
+    }
+
+    public long getTimeStamp() {
+        return timeStamp;
+    }
+
+    public long getReadSyscalls() {
+        return readSyscalls;
+    }
+
+    public long getWriteSyscalls() {
+        return writeSyscalls;
+    }
+
+    public long getCharactersRead() {
+        return charactersRead;
+    }
+
+    public long getCharactersWritten() {
+        return charactersWritten;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessChecker.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,71 @@
+/*
+ * 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.common.portability;
+
+import com.redhat.thermostat.common.portability.internal.windows.WindowsHelperImpl;
+import com.redhat.thermostat.shared.config.OS;
+
+import java.io.File;
+/**
+ * Utility for checking whether a process exists or not.
+ * 
+ * Implementation note: This is Linux specific.
+ *
+ */
+public class ProcessChecker {
+
+    private static final boolean is_linux = OS.IS_LINUX;
+
+    public boolean exists(int pid) {
+        return is_linux ? existsLinux(pid) : existsWindows(pid);
+    }
+
+    private boolean existsLinux(int pid) {
+        File procFile = mapToFile(pid);
+        return procFile.exists();
+    }
+
+    private boolean existsWindows(int pid) {
+        return WindowsHelperImpl.INSTANCE.exists(pid);
+    }
+    
+    // testing-hook
+    File mapToFile(int pid) {
+        return new File("/proc/" + pid);
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessUserInfo.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,74 @@
+/*
+ * 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.common.portability;
+
+import com.redhat.thermostat.common.portability.internal.linux.LinuxProcessUserInfoBuilderImpl;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.internal.windows.WindowsUserInfoBuilderImpl;
+import com.redhat.thermostat.shared.config.OS;
+
+public class ProcessUserInfo {
+
+    private long uid;
+    private String username;
+
+    public ProcessUserInfo(long uid, String username) {
+        this.uid = uid;
+        this.username = username;
+    }
+
+    public ProcessUserInfo() {
+        this.uid = -1;
+        this.username = null;
+    }
+
+    public long getUid() {
+        return uid;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public static ProcessUserInfoBuilder createBuilder(ProcDataSource source, UserNameUtil userNameUtil) {
+        return OS.IS_LINUX ? new LinuxProcessUserInfoBuilderImpl(source, userNameUtil) : new WindowsUserInfoBuilderImpl();
+    }
+
+    public static ProcessUserInfoBuilder createBuilder() {
+        return OS.IS_LINUX ? new LinuxProcessUserInfoBuilderImpl() : new WindowsUserInfoBuilderImpl();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessUserInfoBuilder.java	Mon Jan 23 10:11:31 2017 -0500
@@ -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.common.portability;
+
+/**
+ * Interface for ProcessUserInfo builders
+ */
+public interface ProcessUserInfoBuilder {
+    ProcessUserInfo build(int pid);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/SysConf.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,88 @@
+/*
+ * 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.common.portability;
+
+import com.redhat.thermostat.shared.config.OS;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+/**
+ * A wrapper over POSIX's sysconf.
+ * <p>
+ * Implementation notes: uses {@code getconf(1)}
+ */
+public class SysConf {
+
+    private SysConf() {
+        /* do not initialize */
+    }
+
+    public static long getClockTicksPerSecond() {
+        return OS.IS_LINUX ? getLinuxClockTicksPerSecond() : getWindowsClockTicksPerSecond();
+    }
+
+    private static long getWindowsClockTicksPerSecond() {
+        return PortableHostImpl.INSTANCE.getClockTicksPerSecond();
+    }
+
+    public static long getLinuxClockTicksPerSecond() {
+        String ticks = sysConf("CLK_TCK");
+        try {
+            return Long.valueOf(ticks);
+        } catch (NumberFormatException nfe) {
+            return 0;
+        }
+    }
+
+    private static String sysConf(String arg) {
+        try {
+            Process process = Runtime.getRuntime().exec(new String[] { "getconf", arg });
+            int result = process.waitFor();
+            if (result != 0) {
+                return null;
+            }
+            try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
+                return reader.readLine();
+            }
+        } catch (IOException | InterruptedException e) {
+            return null;
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/UserNameLookupException.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,52 @@
+/*
+ * 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.common.portability;
+
+/**
+ * 
+ * Thrown on user name lookup error.
+ *
+ * @see UserNameUtil
+ */
+@SuppressWarnings("serial")
+public class UserNameLookupException extends Exception {
+
+    public UserNameLookupException(Throwable cause) {
+        super(cause);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/UserNameUtil.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,59 @@
+/*
+ * 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.common.portability;
+
+import com.redhat.thermostat.annotations.Service;
+
+/**
+ * Utility to query the operating system for a user name.
+ */
+@Service
+public interface UserNameUtil {
+
+    /**
+     * Gets the user name corresponding to the provided UID.
+     * 
+     * @param uid
+     *            The UID whose name to return.
+     * @throws UserNameLookupException
+     *            If an error occurred during retrieval of the user name.
+     * @return The user name if found. null if no such UID exists.
+     */
+    String getUserName(long uid) throws UserNameLookupException;
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/Activator.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,59 @@
+/*
+ * 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.common.portability.internal;
+
+import com.redhat.thermostat.common.portability.UserNameUtil;
+import com.redhat.thermostat.common.portability.internal.linux.UserNameUtilImpl;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+
+    @Override
+    public void start(final BundleContext context) throws Exception {
+
+        // No deps, register immediately
+        UserNameUtilImpl usernameUtil = new UserNameUtilImpl();
+        context.registerService(UserNameUtil.class, usernameUtil, null);
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/UnimplementedError.java	Mon Jan 23 10:11:31 2017 -0500
@@ -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.common.portability.internal;
+
+public class UnimplementedError extends Error {
+
+    private final String msg;
+
+    public UnimplementedError(String msg ) {
+        this.msg = msg;
+    }
+
+    public String toString() {
+        return "Unimplemented: " + msg;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxProcessImpl.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,100 @@
+/*
+ * 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.common.portability.internal.linux;
+
+import com.redhat.thermostat.common.Clock;
+import com.redhat.thermostat.common.portability.*;
+import com.redhat.thermostat.common.portability.internal.UnimplementedError;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
+
+import java.util.Map;
+
+public class LinuxProcessImpl implements PortableProcess {
+
+    private final ProcDataSource dataSource;
+
+    public static LinuxProcessImpl INSTANCE = new LinuxProcessImpl(new ProcDataSource());
+
+    LinuxProcessImpl(ProcDataSource ds) {
+        this.dataSource = ds;
+    }
+
+    @Override
+    public boolean exists(int pid) {
+        return new ProcessChecker().exists(pid);
+    }
+
+    @Override
+    public String getUserName(int pid) {
+        throw new UnimplementedError("getUserName()");
+    }
+
+    @Override
+    public int getUid(int pid) {
+        throw new UnimplementedError("getUid()");
+    }
+
+    @Override
+    public Map<String, String> getEnvironment(int pid) {
+        throw new UnimplementedError("getEnvironment()");
+    }
+
+    @Override
+    public PortableProcessStat getProcessStat(int pid) {
+        throw new UnimplementedError("PortableProcessStat()");
+    }
+
+    @Override
+    public PortableVmIoStat getVmIoStat(Clock clock, int pid) {
+        throw new UnimplementedError("getVmIoStat()");
+    }
+
+    @Override
+    public boolean terminateProcess(int pid) {
+        throw new UnimplementedError("terminateProcess()");
+    }
+
+    @Override
+    public boolean terminateProcess(int pid, boolean wait) {
+        throw new UnimplementedError("terminateProcess()");
+    }
+
+    @Override
+    public boolean terminateProcess(int pid, int exitcode, int waitMillis) {
+        throw new UnimplementedError("terminateProcess()");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxProcessUserInfoBuilderImpl.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,118 @@
+/*
+ * 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.common.portability.internal.linux;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.redhat.thermostat.common.portability.UserNameUtil;
+import com.redhat.thermostat.common.portability.ProcessUserInfo;
+import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder;
+import com.redhat.thermostat.common.portability.UserNameLookupException;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
+import com.redhat.thermostat.common.utils.LoggingUtils;
+
+public class LinuxProcessUserInfoBuilderImpl implements ProcessUserInfoBuilder {
+    
+    private static final ProcessUserInfo NON_EXISTENT_USER = new ProcessUserInfo();
+    private static final String PROC_STATUS_UID = "Uid:";
+    private static final Logger logger = LoggingUtils.getLogger(LinuxProcessUserInfoBuilderImpl.class);
+    private ProcDataSource source;
+    private UserNameUtil userNameUtil;
+
+    public LinuxProcessUserInfoBuilderImpl() {
+        this(new ProcDataSource(), new UserNameUtilImpl());
+    }
+
+    public LinuxProcessUserInfoBuilderImpl(ProcDataSource source, UserNameUtil userNameUtil) {
+        this.source = source;
+        this.userNameUtil = userNameUtil;
+    }
+    
+    public ProcessUserInfo build(int pid) {
+        ProcessUserInfo info = NON_EXISTENT_USER;
+        try {
+            Reader reader = source.getStatusReader(pid);
+            long uid = getUidFromProcfs(new BufferedReader(reader));
+            String name = null;
+            try {
+                name = userNameUtil.getUserName(uid);
+            } catch (UserNameLookupException e) {
+                logger.log(Level.WARNING, "Unable to retrieve username for uid: " + uid, e);
+            }
+            info = new ProcessUserInfo(uid, name);
+        } catch (IOException e) {
+            logger.log(Level.WARNING, "Unable to read user info for " + pid, e);
+        }
+        
+        return info;
+    }
+
+    /*
+     * Look for the following line:
+     * Uid:  <RealUid>   <EffectiveUid>   <SavedUid>   <FSUid>
+     */
+    private long getUidFromProcfs(BufferedReader br) throws IOException {
+        long uid = -1;
+        String line;
+        while ((line = br.readLine()) != null) {
+            line = line.trim();
+            if (line.startsWith(PROC_STATUS_UID)) {
+                String[] parts = line.split("\\s+");
+                if (parts.length == 5) {
+                    try {
+                        // Use Real UID
+                        uid = Long.parseLong(parts[1]);
+                    } catch (NumberFormatException e) {
+                        throw new IOException("Unexpected output from ps command", e);
+                    }
+                }
+                else {
+                    throw new IOException("Expected 5 parts from split /proc/${pid}/status output, got " + parts.length);
+                }
+            }
+        }
+        if (uid < 0) {
+            throw new IOException("Unable to determine UID from /proc/${pid}/status");
+        }
+        return uid;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/UserNameUtilImpl.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,72 @@
+/*
+ * 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.common.portability.internal.linux;
+
+import java.io.IOException;
+
+import com.redhat.thermostat.common.portability.UserNameLookupException;
+import com.redhat.thermostat.common.portability.UserNameUtil;
+import com.redhat.thermostat.shared.config.NativeLibraryResolver;
+
+public class UserNameUtilImpl implements UserNameUtil {
+    
+    static {
+        String lib = NativeLibraryResolver.getAbsoluteLibraryPath("UserNameUtilWrapper");
+        System.load(lib);
+    }
+    
+    public String getUserName(long uid) throws UserNameLookupException {
+        String username = null;
+        if (uid >= 0) {
+            try {
+                // getUserName0 may throw IOException. We catch it here and
+                // throw a more specific exception in order to avoid API 
+                // leakage. This exception is then dealt with in the caller of
+                // this method rather than here. This free's us from using the
+                // logger in a JNI class.
+                username = getUserName0(uid);
+            } catch (IOException e) {
+                throw new UserNameLookupException(e);
+            }
+        }
+        return username;
+    }
+    
+    private native String getUserName0(long uid) throws IOException;
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImpl.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,254 @@
+/*
+ * 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.common.portability.internal.windows;
+
+import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.shared.config.NativeLibraryResolver;
+import com.redhat.thermostat.shared.config.OS;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+
+/**
+ * Utility class to access Windows native code
+ */
+public class WindowsHelperImpl {
+
+    private static final Logger logger = LoggingUtils.getLogger(WindowsHelperImpl.class);
+
+    public static WindowsHelperImpl INSTANCE;
+
+    /*
+     // from MemoryStatusEx (8 values)
+        DWORD     dwMemoryLoad;
+        DWORDLONG ullTotalPhys;
+        DWORDLONG ullAvailPhys;
+        DWORDLONG ullTotalPageFile;
+        DWORDLONG ullAvailPageFile;
+        DWORDLONG ullTotalVirtual;
+        DWORDLONG ullAvailVirtual;
+        DWORDLONG ullAvailExtendedVirtual;
+
+     // from PERFORMANCE_INFORMATION (13 values)
+        SIZE_T CommitTotal;
+        SIZE_T CommitLimit;
+        SIZE_T CommitPeak;
+        SIZE_T PhysicalTotal;
+        SIZE_T PhysicalAvailable;
+        SIZE_T SystemCache;
+        SIZE_T KernelTotal;
+        SIZE_T KernelPaged;
+        SIZE_T KernelNonpaged;
+        SIZE_T PageSize;
+        DWORD  HandleCount;
+        DWORD  ProcessCount;
+        DWORD  ThreadCount;
+     */
+
+    static {
+        if (OS.IS_WINDOWS) {
+            String lib = NativeLibraryResolver.getAbsoluteLibraryPath("WindowsHelperWrapper");
+            try {
+                System.load(lib);
+                INSTANCE = new WindowsHelperImpl();
+            } catch (UnsatisfiedLinkError e) {
+                logger.severe("Could not load WindowsHelperImpl DLL:" + lib);
+                INSTANCE = null;
+                // do not throw here, because you'll get a NoClassDefFound thrown when running other tests that Mock this class
+            }
+        } else {
+            INSTANCE = null;
+        }
+    }
+
+    private WindowsHelperImpl() {
+    }
+    // local host-wide information
+
+    public String getHostName() {
+        return getHostName0(true);
+    }
+
+    public String getOSName() {
+        return System.getProperty("os.name");
+    }
+
+    public String getOSVersion() {
+        final long info[] = new long[3];  // major, minor, build
+        getOSVersion0(info);
+        return "" + info[0] + "" + info[1] + " (Build " + info[2] + ")";
+    }
+
+    public String getCPUModel() {
+        return getCPUString0();
+    }
+
+    public int getCPUCount() {
+        return getCPUCount0();
+    }
+
+    public long getTotalMemory() {
+        final long info[] = getMemoryInfo();
+        return info[1]; // totalPhysical
+    }
+
+    long[] getMemoryInfo() {
+        final long[] mi = new long[8];
+        getGlobalMemoryStatus0(mi);
+        return mi;
+    }
+
+    private long[] getPerformanceInfo() {
+        final long[] mi = new long[13];
+        getPerformanceInfo0(mi);
+        return mi;
+    }
+
+    public long getClockTicksPerSecond() {
+        // we "know" this is 10E7 (units from  getProcessStat)
+        // but calculate it anyways from current process
+        final long[] info = INSTANCE.getProcessCPUInfo(0);
+        return info[4];
+    }
+
+    // local process-specific information
+
+    public boolean exists(int pid) {
+        final long hnd = getLimitedProcessHandle0(pid);
+        if (hnd != 0) {
+            closeHandle0(hnd);
+        }
+        return hnd != 0;
+    }
+
+    public String getUserName(int pid) {
+        return getUserName0(pid,true);
+    }
+
+    public int getUid(int pid) {
+        final String sid = getProcessSID0(pid);
+        if (sid == null) {
+            return -1;
+        }
+        final int idx = sid.lastIndexOf('-');
+        final String uidStr = sid.substring(idx+1);
+        return Integer.parseInt(uidStr);
+    }
+
+    public Map<String, String> getEnvironment(int pid) {
+        // the environment is returned as a 1D array of alternating env names and values
+        final String[] envArray = getEnvironment0(pid);
+        if (envArray == null || envArray.length == 0) {
+            return Collections.emptyMap();
+        }
+
+        if (envArray.length % 2 != 0) {
+            throw new AssertionError("environment array length not even");
+        }
+
+        final Map<String, String> env = new HashMap<>(envArray.length/2);
+        for (int i = 0; i < envArray.length / 2; i++) {
+            env.put(envArray[i * 2], envArray[i * 2 + 1]);
+        }
+        return env;
+    }
+
+    /**
+     * fetch process counters
+     * @param pid process id
+     * @return long[] working set size, user time, kernel time, (todo: elapsed time), ticks per second
+     */
+    long[] getProcessCPUInfo(int pid) {
+        final long[] info = new long[5];
+        getProcessInfo0(pid, info);
+        return info;
+    }
+
+    long[] getProcessMemInfo(int pid) {
+        final long[] info = new long[5];
+        getProcessInfo0(pid, info);
+        return info;
+    }
+
+    long[] getProcessIOInfo(int pid) {
+        final long info[] = new long[6];
+        getProcessIOInfo0(pid,info);
+        return info;
+    }
+
+    public long getProcessHandle(int pid) {
+        return getProcessHandle0(pid);
+    }
+
+    public void closeHandle(long handle) {
+        closeHandle0(handle);
+    }
+
+    public boolean terminateProcess(int pid) {
+        return terminateProcess0(pid,0, -1);
+    }
+
+    public boolean terminateProcess(int pid, boolean wait) {
+        return terminateProcess0(pid,0, 0);
+    }
+
+    public boolean terminateProcess(int pid, int exitcode, int waitMillis) {
+        return terminateProcess0(pid, exitcode, waitMillis);
+    }
+
+    private static native String getHostName0(boolean prependDomain);
+    private static native void getOSVersion0(long[] versionAndBuild);
+    private static native boolean getGlobalMemoryStatus0(long[] info);
+    private static native boolean getPerformanceInfo0(long[] info);
+    private static native String getCPUString0();
+    private static native int getCPUCount0();
+    private static native long queryPerformanceFrequency0();
+
+    private static native String getProcessSID0(int pid);
+    private static native String getUserName0(int pid, boolean prependDomain);
+    private static native String[] getEnvironment0(int pid);
+    private static native boolean getProcessInfo0(int pid, long[] info);
+    private static native boolean getProcessIOInfo0(int pid, long[] info);
+
+    private static native long getCurrentProcessHandle0();
+    private static native long getProcessHandle0(int pid);
+    private static native long getLimitedProcessHandle0(int pid);
+    private static native void closeHandle0(long handle);
+    private static native boolean terminateProcess0(int pid, int exitCode, int waitMillis);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHostImpl.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,86 @@
+/*
+ * 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.common.portability.internal.windows;
+
+import com.redhat.thermostat.common.portability.PortableHost;
+import com.redhat.thermostat.common.portability.PortableMemoryStat;
+
+public class WindowsHostImpl implements PortableHost {
+
+    public static final WindowsHostImpl INSTANCE = new WindowsHostImpl();
+    private static final WindowsHelperImpl helper = WindowsHelperImpl.INSTANCE;
+
+    @Override
+    public String getHostName() {
+        return helper.getHostName();
+    }
+
+    @Override
+    public String getOSName() {
+        return helper.getOSName();
+    }
+
+    @Override
+    public String getOSVersion() {
+        return helper.getOSVersion();
+    }
+
+    @Override
+    public String getCPUModel() {
+        return helper.getCPUModel();
+    }
+
+    @Override
+    public int getCPUCount() {
+        return helper.getCPUCount();
+    }
+
+    @Override
+    public long getTotalMemory() {
+        return helper.getTotalMemory();
+    }
+
+    @Override
+    public long getClockTicksPerSecond() {
+        return helper.getClockTicksPerSecond();
+    }
+
+    @Override
+    public PortableMemoryStat getMemoryStat() {
+        return new WindowsMemoryStat();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsMemoryStat.java	Mon Jan 23 10:11:31 2017 -0500
@@ -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.common.portability.internal.windows;
+
+import com.redhat.thermostat.common.portability.PortableMemoryStat;
+
+class WindowsMemoryStat extends PortableMemoryStat {
+
+    WindowsMemoryStat() {
+        this(WindowsHelperImpl.INSTANCE.getMemoryInfo());
+    }
+
+    private WindowsMemoryStat(final long[] info) {
+        super(System.currentTimeMillis(), info[1], info[2], 0, 0, info[3], info[4], 0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsProcessImpl.java	Mon Jan 23 10:11:31 2017 -0500
@@ -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.common.portability.internal.windows;
+
+import com.redhat.thermostat.common.Clock;
+import com.redhat.thermostat.common.portability.PortableProcess;
+import com.redhat.thermostat.common.portability.PortableProcessStat;
+import com.redhat.thermostat.common.portability.PortableVmIoStat;
+
+import java.util.Map;
+
+public class WindowsProcessImpl implements PortableProcess {
+
+    public static final WindowsProcessImpl INSTANCE = new WindowsProcessImpl();
+    private static final WindowsHelperImpl helper = WindowsHelperImpl.INSTANCE;
+
+    @Override
+    public boolean exists(int pid) {
+        return helper.exists(pid);
+    }
+
+    @Override
+    public String getUserName(int pid) {
+        return helper.getUserName(pid);
+    }
+
+    @Override
+    public int getUid(int pid) {
+        return helper.getUid(pid);
+    }
+
+    @Override
+    public Map<String, String> getEnvironment(int pid) {
+        return helper.getEnvironment(pid);
+    }
+
+    @Override
+    public PortableProcessStat getProcessStat(int pid) {
+        final long[] info = helper.getProcessCPUInfo(pid);
+        final long utime = info[1];
+        final long stime = info[2];
+        return new PortableProcessStat(pid, utime, stime);
+    }
+
+    @Override
+    public PortableVmIoStat getVmIoStat(Clock clock, int pid) {
+        return new WindowsVmIoStat(clock, pid);
+    }
+
+    @Override
+    public boolean terminateProcess(int pid) {
+        return helper.terminateProcess(pid);
+    }
+
+    @Override
+    public boolean terminateProcess(int pid, boolean wait) {
+        return helper.terminateProcess(pid, wait);
+    }
+
+    @Override
+    public boolean terminateProcess(int pid, int exitcode, int waitMillis) {
+        return helper.terminateProcess(pid, exitcode, waitMillis);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsUserInfoBuilderImpl.java	Mon Jan 23 10:11:31 2017 -0500
@@ -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.common.portability.internal.windows;
+
+import com.redhat.thermostat.common.portability.PortableProcessImpl;
+import com.redhat.thermostat.common.portability.ProcessUserInfo;
+import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder;
+import com.redhat.thermostat.common.portability.PortableProcess;
+import com.redhat.thermostat.common.utils.LoggingUtils;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Build User information via Windows helper classes
+ */
+public class WindowsUserInfoBuilderImpl implements ProcessUserInfoBuilder {
+
+    private final PortableProcess procHelper;
+
+    private static final ProcessUserInfo NON_EXISTENT_USER = new ProcessUserInfo();
+    private static final Logger logger = LoggingUtils.getLogger(WindowsUserInfoBuilderImpl.class);
+
+    public WindowsUserInfoBuilderImpl() {
+        this(PortableProcessImpl.INSTANCE);
+    }
+
+    WindowsUserInfoBuilderImpl(PortableProcess helper) {
+        this.procHelper = helper;
+    }
+
+    @Override
+    public ProcessUserInfo build(int pid) {
+        ProcessUserInfo info = NON_EXISTENT_USER;
+        try {
+            final long uid = procHelper.getUid(pid);
+            final String name = procHelper.getUserName(pid);
+            info = new ProcessUserInfo(uid, name);
+        } catch (Exception e) {
+            logger.log(Level.WARNING, "Unable to read user info for " + pid, e);
+        }
+
+        return info;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsVmIoStat.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,51 @@
+/*
+ * 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.common.portability.internal.windows;
+
+import com.redhat.thermostat.common.Clock;
+import com.redhat.thermostat.common.portability.PortableVmIoStat;
+
+class WindowsVmIoStat extends PortableVmIoStat {
+
+    WindowsVmIoStat(Clock clock, int pid) {
+        this(clock, WindowsHelperImpl.INSTANCE.getProcessIOInfo(pid));
+    }
+
+    private WindowsVmIoStat(Clock clock, final long info[]) {
+        super(clock.getRealTimeMillis(), info[0], info[1], info[2], info[3]);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/linux/ProcDataSource.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,125 @@
+/*
+ * 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.common.portability.linux;
+
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * Wrapper for files under {@code /proc/}. See proc(5) for details about this.
+ *
+ * This class is inherently unportable, but a _lot_ of Linux code would need refactoring
+ * before it can be unexported from the portability package.
+ *
+ * Note that different Unix-like OSs may or may not have a /proc (and the format may be different)
+ * for example Darwin/OSX doesn't have /proc
+ */
+public class ProcDataSource {
+
+    private static final String LOAD_FILE = "/proc/loadavg";
+    private static final String STAT_FILE = "/proc/stat";
+    private static final String MEMINFO_FILE = "/proc/meminfo";
+    private static final String CPUINFO_FILE = "/proc/cpuinfo";
+
+    private static final String PID_ENVIRON_FILE = "/proc/${pid}/environ";
+    private static final String PID_IO_FILE = "/proc/${pid}/io";
+    private static final String PID_STAT_FILE = "/proc/${pid}/stat";
+    private static final String PID_STATUS_FILE = "/proc/${pid}/status";
+
+    /**
+     * Returns a reader for /proc/cpuinfo
+     */
+    public Reader getCpuInfoReader() throws IOException {
+        return new FileReader(CPUINFO_FILE);
+    }
+
+    /**
+     * Returns a reader for /proc/loadavg
+     */
+    public Reader getCpuLoadReader() throws IOException {
+        return new FileReader(LOAD_FILE);
+    }
+
+    /**
+     * Returns a reader for /proc/stat. Kernel/System statistics.
+     */
+    public Reader getStatReader() throws IOException {
+        return new FileReader(STAT_FILE);
+    }
+
+    /**
+     * Returns a reader for /proc/meminfo
+     */
+    public Reader getMemInfoReader() throws IOException {
+        return new FileReader(MEMINFO_FILE);
+    }
+
+    /**
+     * Returns a reader for /proc/$PID/environ
+     */
+    public Reader getEnvironReader(int pid) throws IOException {
+        return new FileReader(getPidFile(PID_ENVIRON_FILE, pid));
+    }
+
+    /**
+     * Returns a reader for /proc/$PID/io
+     */
+    public Reader getIoReader(int pid) throws IOException {
+        return new FileReader(getPidFile(PID_IO_FILE, pid));
+    }
+
+    /**
+     * Returns a reader for /proc/$PID/stat
+     */
+    public Reader getStatReader(int pid) throws IOException {
+        return new FileReader(getPidFile(PID_STAT_FILE, pid));
+    }
+    
+    /**
+     * Returns a reader for /proc/$PID/status
+     */
+    public Reader getStatusReader(int pid) throws IOException {
+        return new FileReader(getPidFile(PID_STATUS_FILE, pid));
+    }
+
+    private String getPidFile(String fileName, int pid) {
+        return fileName.replace("${pid}", Integer.toString(pid));
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/package-info.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+
+/**
+ * Utilities to help with username lookups
+ */
+package com.redhat.thermostat.common.portability;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/native/HostName.c	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+#include "com_redhat_thermostat_common_portability_HostName.h"
+
+#include <jni.h>
+#include <unistd.h>
+#include <string.h>
+
+#if !defined(_WIN32)
+# include <netdb.h>
+#else // windows
+# include <winsock2.h>
+#endif
+
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 1025
+#endif /* NI_MAXHOST */
+
+JNIEXPORT jstring JNICALL
+Java_com_redhat_thermostat_common_portability_HostName_getHostName
+  (JNIEnv *env, jclass HostNameClass)
+{
+    char hostname[NI_MAXHOST];
+    memset(hostname, 0, sizeof(hostname));
+
+    if (gethostname(hostname,  sizeof(hostname)) == 0) {
+        return (*env)->NewStringUTF(env, hostname);
+    }
+    return NULL;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/native/UserNameUtilImpl.c	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+
+#include "com_redhat_thermostat_common_portability_internal_linux_UserNameUtilImpl.h"
+
+#include <jni.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if !defined(_WIN32)
+# include <pwd.h>
+#else // windows
+#endif
+
+static jint throw_IOException(JNIEnv *env, const char *message) {
+    const char *class_name = "java/io/IOException";
+    jclass class = (*env)->FindClass(env, class_name);
+    if (class == NULL) {
+        return -1;
+    }
+    return (*env)->ThrowNew(env, class, message);
+}
+
+#if !defined(_WIN32)
+
+JNIEXPORT jstring JNICALL
+Java_com_redhat_thermostat_common_portability_internal_linux_UserNameUtilImpl_getUserName0
+    (JNIEnv *env, jclass ProcessUserInfoBuilderClass, jlong uid) {
+    size_t bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+    if (bufsize < 0) {
+        throw_IOException(env, "Unable to retrieve recommended buffer size from sysconf");
+        return NULL;
+    }
+
+    char *buf = malloc(bufsize * sizeof(char));
+    if (!buf) {
+        throw_IOException(env, "Unable to allocate buffer for username");
+        return NULL;
+    }
+
+    struct passwd pwd;
+    struct passwd *ret;
+    int rc = getpwuid_r(uid, &pwd, buf, bufsize, &ret);
+    if (rc) {
+        // Error occurred
+        const char *error_message = strerror(rc);
+        throw_IOException(env, error_message);
+        free(buf);
+        return NULL;
+    }
+    if (!ret) {
+        // No username found
+        char err_buf[128]; // Large enough for even the largest UIDs
+        snprintf(err_buf, sizeof(err_buf), "Username not found for uid: %ld", uid);
+        throw_IOException(env, err_buf);
+        free(buf);
+        return NULL;
+    }
+
+    jstring name = (*env)->NewStringUTF(env, pwd.pw_name);
+    free(buf);
+    return name;
+}
+
+#else // Windows
+JNIEXPORT jstring JNICALL
+Java_com_redhat_thermostat_common_portability_internal_linux_UserNameUtilImpl_getUserName0
+    (JNIEnv *env, jclass ProcessUserInfoBuilderClass, jlong uid) {
+
+    // TODO
+    throw_IOException(env, "UserNameUtilImpl.getUserName() no yet implemented on Windows");
+    jstring name = (*env)->NewStringUTF(env, "xxxuserxxx");
+    return name;
+}
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/main/native/WindowsHelperImpl.c	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,614 @@
+/*
+ * 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.
+ */
+
+#include "com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl.h"
+#include <jni.h>
+#include <unistd.h>
+#include <string.h>
+
+#if !defined(_WIN32)
+# include <netdb.h>
+#else // windows
+# include <winsock2.h>
+# include <psapi.h>
+# include <intrin.h>
+#endif
+
+#define MAX_NAME 256
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 1025
+#endif /* NI_MAXHOST */
+
+#if defined(DEBUG)
+static void testLength(JNIEnv* env, jlongArray array, int minLength) {
+    // sanity test
+    jsize len = (*env)->GetArrayLength(env, array);
+    assert(len >= minLength);
+}
+#else
+static void testLength(JNIEnv* env, jlongArray array, int minLength) {}
+#endif
+
+/*
+ * Class:     com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl
+ * Method:    getHostName0
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getHostName0
+  (JNIEnv *env, jclass winHelperClass, jboolean prependDomain)
+{
+      char hostname[NI_MAXHOST];
+      memset(hostname, 0, sizeof(hostname));
+
+      if (gethostname(hostname,  sizeof(hostname)) == 0) {
+          return (*env)->NewStringUTF(env, hostname);
+      }
+      return NULL;
+}
+
+/*
+ * Class:     com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl
+ * Method:    getOSVersion0
+ * Signature: ([J)V
+ */
+JNIEXPORT void JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getOSVersion0
+  (JNIEnv *env, jclass winHelperClass, jlongArray array)
+{
+    testLength(env, array, 3);
+
+    // Get the element pointer
+    jlong* data = (*env)->GetLongArrayElements(env, array, 0);
+
+    OSVERSIONINFOEX vinfo;
+    vinfo.dwOSVersionInfoSize = sizeof(vinfo);
+    GetVersionEx(&vinfo);
+    data[0] = vinfo.dwMajorVersion;
+    data[1] = vinfo.dwMinorVersion;
+    data[2] = vinfo.dwBuildNumber;
+
+    (*env)->ReleaseLongArrayElements(env, array, data, 0);
+}
+
+
+/*
+ * Class:     com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl
+ * Method:    getGlobalMemoryStatus0
+ * Signature: ([J)V
+ */
+JNIEXPORT boolean JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getGlobalMemoryStatus0
+  (JNIEnv *env, jclass winHelperClass, jlongArray array)
+{
+    testLength(env, array, 8);
+
+    // Get the element pointer
+    jlong* data = (*env)->GetLongArrayElements(env, array, 0);
+
+    // get the memory info
+    MEMORYSTATUSEX statex;
+    statex.dwLength = sizeof(statex);
+    GlobalMemoryStatusEx(&statex);
+    data[0] = statex.dwMemoryLoad;
+    data[1] = statex.ullTotalPhys;
+    data[2] = statex.ullAvailPhys;
+    data[3] = statex.ullTotalPageFile;
+    data[4] = statex.ullAvailPageFile;
+    data[5] = statex.ullTotalVirtual;
+    data[6] = statex.ullAvailVirtual;
+    data[7] = statex.ullAvailExtendedVirtual;
+
+    (*env)->ReleaseLongArrayElements(env, array, data, 0);
+    return TRUE;
+}
+
+/*
+ * Class:     com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl
+ * Method:    getPerformanceInfo0
+ * Signature: ([J)V
+ */
+JNIEXPORT boolean JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getPerformanceInfo0
+  (JNIEnv *env, jclass winHelperClass, jlongArray array)
+{
+    testLength(env, array, 13);
+
+    // Get the element pointer
+    jlong* data = (*env)->GetLongArrayElements(env, array, 0);
+
+    /**
+     // from PERFORMANCE_INFORMATION (13 values)
+        SIZE_T CommitTotal;
+        SIZE_T CommitLimit;
+        SIZE_T CommitPeak;
+        SIZE_T PhysicalTotal;
+        SIZE_T PhysicalAvailable;
+        SIZE_T SystemCache;
+        SIZE_T KernelTotal;
+        SIZE_T KernelPaged;
+        SIZE_T KernelNonpaged;
+        SIZE_T PageSize;
+        DWORD  HandleCount;
+        DWORD  ProcessCount;
+        DWORD  ThreadCount;
+     */
+
+    // get the memeory info
+    PERFORMANCE_INFORMATION statex;
+    statex.cb = sizeof(statex);
+    GetPerformanceInfo(&statex, statex.cb);
+    data[0] = statex.CommitTotal;
+    data[1] = statex.CommitLimit;
+    data[2] = statex.CommitPeak;
+    data[3] = statex.PhysicalTotal;
+    data[4] = statex.PhysicalAvailable;
+    data[5] = statex.SystemCache;
+    data[6] = statex.KernelTotal;
+    data[7] = statex.KernelPaged;
+    data[8] = statex.KernelNonpaged;
+    data[9] = statex.PageSize;
+    data[10] = statex.HandleCount;
+    data[11] = statex.ProcessCount;
+    data[12] = statex.ThreadCount;
+
+    (*env)->ReleaseLongArrayElements(env, array, data, 0);
+    return TRUE;
+}
+
+
+/*
+ * Class:     com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl
+ * Method:    getCPUString0
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getCPUString0
+  (JNIEnv *env, jclass winHelperClass)
+{
+    // Get extended ids.
+    int CPUInfo[4] = {-1};
+    __cpuid(CPUInfo, 0x80000000);
+    unsigned int nExIds = CPUInfo[0];
+
+    // Get the information associated with each extended ID.
+    char CPUBrandString[0x40] = { 0 };
+    for( unsigned int i=0x80000000; i<=nExIds; ++i)
+    {
+        __cpuid(CPUInfo, i);
+
+        // Interpret CPU brand string and cache information.
+        if  (i == 0x80000002)
+        {
+            memcpy( CPUBrandString,
+            CPUInfo,
+            sizeof(CPUInfo));
+        }
+        else if( i == 0x80000003 )
+        {
+            memcpy( CPUBrandString + 16,
+            CPUInfo,
+            sizeof(CPUInfo));
+        }
+        else if( i == 0x80000004 )
+        {
+            memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
+        }
+    }
+    return (*env)->NewStringUTF(env, CPUBrandString);
+
+}
+
+/*
+ * Class:     com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl
+ * Method:    getCPUCount0
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getCPUCount0
+  (JNIEnv *env, jclass winHelperClass)
+{
+    SYSTEM_INFO sysinfo;
+    GetSystemInfo(&sysinfo);
+
+    return sysinfo.dwNumberOfProcessors;
+}
+
+/*
+ * Class:     com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl
+ * Method:    queryPerformanceFrequency0
+ * Signature: ()I
+ */
+JNIEXPORT jlong JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_queryPerformanceFrequency0
+  (JNIEnv *env, jclass winHelperClass)
+{
+    LARGE_INTEGER freq;
+    QueryPerformanceFrequency(&freq);
+
+    return (jlong)(freq.QuadPart);
+}
+
+/*
+ * Class:     com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl
+ * Method:    getProcessSID0
+ * Signature: (I)I
+ */
+JNIEXPORT jstring JNICALL
+Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getProcessSID0
+  (JNIEnv *env, jclass winHelperClass, jint pid)
+{
+    HANDLE hProcess;
+
+    hProcess = (pid == 0) ? GetCurrentProcess() : OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid );
+    if (NULL == hProcess)
+        return NULL;
+
+    HANDLE hToken = NULL;
+
+    if( !OpenProcessToken( hProcess, TOKEN_QUERY, &hToken ) ) {
+        CloseHandle( hProcess );
+        return NULL;
+    }
+
+    DWORD dwSize = MAX_NAME;
+    DWORD dwLength = 0;
+    PTOKEN_USER ptu = NULL;
+
+    if (!GetTokenInformation(
+        hToken,         // handle to the access token
+        TokenUser,      // get information about the token's groups
+        (LPVOID) ptu,   // pointer to PTOKEN_USER buffer
+        0,              // size of buffer
+        &dwLength       // receives required buffer size
+    )) {
+        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+            CloseHandle( hToken );
+            CloseHandle( hProcess );
+            return NULL;
+        }
+
+        ptu = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
+
+        if (ptu == NULL) {
+            CloseHandle( hToken );
+            CloseHandle( hProcess );
+            return NULL;
+        }
+    }
+
+    if (!GetTokenInformation(
+         hToken,         // handle to the access token
+         TokenUser,      // get information about the token's groups
+         (LPVOID) ptu,   // pointer to PTOKEN_USER buffer
+         dwLength,       // size of buffer
+         &dwLength       // receives required buffer size
+         )) {
+        if (ptu != NULL) {
+            HeapFree(GetProcessHeap(), 0, (LPVOID)ptu);
+        }
+        CloseHandle( hToken );
+        CloseHandle( hProcess );
+        return NULL;
+    }
+
+    LPWSTR stringSid;
+    ConvertSidToStringSidW( ptu->User.Sid, &stringSid );
+    jstring s = (*env)->NewString(env, (const jchar *)stringSid, (jsize)wcslen(stringSid));
+
+    LocalFree(stringSid);
+
+    if (ptu != NULL) {
+        HeapFree(GetProcessHeap(), 0, (LPVOID)ptu);
+    }
+    CloseHandle( hToken );
+    CloseHandle( hProcess );
+    return s;
+}
+
+/*
+ * Class:     com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl
+ * Method:    getUserName0
+ * Signature: (I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getUserName0
+  (JNIEnv *env, jclass winHelperClass, jint pid, jboolean prependDomain)
+{
+    HANDLE hProcess;
+
+    hProcess = (pid == 0) ? GetCurrentProcess() : OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid );
+    if (NULL == hProcess)
+        return NULL;
+
+    HANDLE hToken = NULL;
+
+    if( !OpenProcessToken( hProcess, TOKEN_QUERY, &hToken ) ) {
+        CloseHandle( hProcess );
+        return NULL;
+    }
+
+    DWORD dwSize = MAX_NAME;
+    DWORD dwLength = 0;
+    PTOKEN_USER ptu = NULL;
+
+    if (!GetTokenInformation(
+        hToken,         // handle to the access token
+        TokenUser,      // get information about the token's groups
+        (LPVOID) ptu,   // pointer to PTOKEN_USER buffer
+        0,              // size of buffer
+        &dwLength       // receives required buffer size
+    )) {
+        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+            CloseHandle( hToken );
+            CloseHandle( hProcess );
+            return NULL;
+        }
+
+        ptu = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
+
+        if (ptu == NULL) {
+            CloseHandle( hToken );
+            CloseHandle( hProcess );
+            return NULL;
+        }
+    }
+
+    if (!GetTokenInformation(
+         hToken,         // handle to the access token
+         TokenUser,      // get information about the token's groups
+         (LPVOID) ptu,   // pointer to PTOKEN_USER buffer
+         dwLength,       // size of buffer
+         &dwLength       // receives required buffer size
+         )) {
+        if (ptu != NULL) {
+            HeapFree(GetProcessHeap(), 0, (LPVOID)ptu);
+        }
+        CloseHandle( hToken );
+        CloseHandle( hProcess );
+        return NULL;
+    }
+
+    SID_NAME_USE SidType;
+    wchar_t lpName[MAX_NAME];
+    wchar_t lpDomain[MAX_NAME*2 + 1];  // room for '\' + lpName
+    jstring s = NULL;
+
+    if( !LookupAccountSidW( NULL , ptu->User.Sid, lpName, &dwSize, lpDomain, &dwSize, &SidType ) )
+    {
+        DWORD dwResult = GetLastError();
+        if( dwResult == ERROR_NONE_MAPPED )
+           strcpy (lpName, "NONE_MAPPED" );
+        else
+        {
+            printf("LookupAccountSid Error %u\n", GetLastError());
+        }
+    }
+    else
+    {
+        if (prependDomain) {
+            wcscat(lpDomain, L"\\");
+            wcscat(lpDomain, lpName);
+            s = (*env)->NewString(env, (const jchar *)lpDomain, (jsize)wcslen(lpDomain));
+        }
+        else {
+            s = (*env)->NewString(env, (const jchar *)lpName, (jsize)wcslen(lpName));
+        }
+    }
+
+    if (ptu != NULL) {
+        HeapFree(GetProcessHeap(), 0, (LPVOID)ptu);
+    }
+    CloseHandle( hToken );
+    CloseHandle( hProcess );
+    return s;
+}
+
+/*
+ * Class:     com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl
+ * Method:    getEnvironment0
+ * Signature: ()[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getEnvironment0
+  (JNIEnv *env, jclass winHelperClass, jint pid)
+{
+    // TODO - implement this stub - not eay (have to open the process memory and poke around)
+    // for now, return an empty array
+    jobjectArray ret = (jobjectArray)(*env)->NewObjectArray(env, 0, (*env)->FindClass(env, "java/lang/String"), (*env)->NewStringUTF(env, ""));
+    return ret;
+}
+
+static unsigned __int64 convertFileTimeToInt64( const FILETIME * pFileTime )
+{
+  ULARGE_INTEGER largeInt;
+
+  largeInt.LowPart = pFileTime->dwLowDateTime;
+  largeInt.HighPart = pFileTime->dwHighDateTime;
+
+  return largeInt.QuadPart;
+}
+
+/*
+ * Class:     com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl
+ * Method:    getProcessMemoryInfo0
+ * Signature: (I[J)V
+ */
+JNIEXPORT jboolean JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getProcessInfo0
+  (JNIEnv *env, jclass winHelperClass, jint pid, jlongArray array)
+{
+    testLength(env, array, 4);
+
+    HANDLE hProcess;
+    PROCESS_MEMORY_COUNTERS pmc;
+
+    hProcess = (pid == 0) ? GetCurrentProcess() : OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid );
+    if (NULL == hProcess)
+        return FALSE;
+
+    // Get the element pointer
+    jlong* data = (*env)->GetLongArrayElements(env, array, 0);
+
+    pmc.cb = sizeof(pmc);
+    if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) ) {
+        data[0] = pmc.WorkingSetSize;
+    }
+    else {
+        (*env)->ReleaseLongArrayElements(env, array, data, 0);
+        return FALSE;
+    }
+
+    FILETIME creationTime;
+    FILETIME exitTime;
+    FILETIME kernelTime;
+    FILETIME userTime;
+
+    if ( GetProcessTimes( hProcess, &creationTime, &exitTime, &kernelTime, &userTime ) ) {
+        // times returned from GetProcessTimes() are in 100-nanosecond units.
+        data[1] = convertFileTimeToInt64(&userTime);
+        data[2] = convertFileTimeToInt64(&kernelTime);
+        data[3] = convertFileTimeToInt64(&creationTime);
+        data[4] = 10000000; // 100 nanonseconds is this many ticks per second
+    }
+
+    CloseHandle(hProcess);
+
+    (*env)->ReleaseLongArrayElements(env, array, data, 0);
+    return TRUE;
+}
+
+/*
+ * Class:     com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl
+ * Method:    getProcessIOInfo0
+ * Signature: (I[J)V
+ */
+JNIEXPORT jboolean JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getProcessIOInfo0
+  (JNIEnv *env, jclass winHelperClass, jint pid, jlongArray array)
+{
+    testLength(env, array, 6);
+
+    HANDLE hProcess;
+    IO_COUNTERS iocounters;
+
+    hProcess = (pid == 0) ? GetCurrentProcess() : OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid );
+    if (NULL == hProcess)
+        return FALSE;
+
+    BOOL rc = GetProcessIoCounters( hProcess, &iocounters );
+    if (!rc) {
+        CloseHandle(hProcess);
+        return FALSE;
+    }
+
+    // Get the element pointer
+    jlong* data = (*env)->GetLongArrayElements(env, array, 0);
+
+    data[0] = iocounters.ReadOperationCount;
+    data[1] = iocounters.WriteOperationCount;
+    data[2] = iocounters.ReadTransferCount;
+    data[3] = iocounters.WriteTransferCount;
+    data[4] = iocounters.OtherOperationCount;
+    data[5] = iocounters.OtherTransferCount;
+
+    (*env)->ReleaseLongArrayElements(env, array, data, 0);
+    CloseHandle(hProcess);
+    return TRUE;
+}
+
+
+/*
+ * Class:     com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl
+ * Method:    getProcessHandle0
+ * Signature: (I)J
+ */
+JNIEXPORT jlong JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getCurrentProcessHandle0
+  (JNIEnv *env, jclass winHelperClass) {
+
+    HANDLE hProcess;
+    hProcess = GetCurrentProcess();
+    return (jlong) hProcess;
+}
+
+/*
+ * Class:     com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl
+ * Method:    getProcessHandle0
+ * Signature: (I)J
+ */
+JNIEXPORT jlong JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getProcessHandle0
+  (JNIEnv *env, jclass winHelperClass, jint pid) {
+
+    HANDLE hProcess = (pid == 0) ? GetCurrentProcess() : OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid );
+    return (jlong) hProcess;
+}
+
+/*
+ * Class:     com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl
+ * Method:    getLimitedProcessHandle0
+ * Signature: (I)J
+ */
+JNIEXPORT jlong JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_getLimitedProcessHandle0
+  (JNIEnv *env, jclass winHelperClass, jint pid) {
+
+    HANDLE hProcess = (pid == 0) ? GetCurrentProcess() : OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid );
+    return (jlong) hProcess;
+}
+
+/*
+ * Class:     com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl
+ * Method:    closeHandle0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_closeHandle0
+  (JNIEnv *env, jclass winHelperClass, jlong handle){
+
+    CloseHandle((HANDLE)handle);
+}
+
+/*
+ * Class:     com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl
+ * Method:    terminateProcess0
+ * Signature: (IIB)V
+ */
+JNIEXPORT jboolean JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_terminateProcess0
+  (JNIEnv *env, jclass winHelperClass, jint pid, jint exitCode, jint waitMillis) {
+
+    HANDLE hProcess = (pid == 0) ? GetCurrentProcess() : OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid );
+    if (!hProcess) {
+        return FALSE;
+    }
+    TerminateProcess(hProcess, (unsigned int)exitCode);
+    if (waitMillis >= 0) {
+        WaitForSingleObject(hProcess, waitMillis);
+    }
+    CloseHandle(hProcess);
+    return TRUE;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/ProcessCheckerTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,74 @@
+/*
+ * 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.common.portability;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+
+import com.redhat.thermostat.common.portability.ProcessChecker;
+import org.junit.Test;
+
+public class ProcessCheckerTest {
+
+    private static final int SOME_PID = 80980;
+    
+    @Test
+    public void testProcessExists() {
+        basicTest(true);
+    }
+    
+    @Test
+    public void testProcessNotExisting() {
+        basicTest(false);
+    }
+    
+    private void basicTest(boolean expected) {
+        final File baseFile = mock(File.class);
+        when(baseFile.exists()).thenReturn(expected);
+        ProcessChecker process = new ProcessChecker() {
+            @Override
+            File mapToFile(int pid) {
+                assertEquals(SOME_PID, pid);
+                return baseFile;
+            }
+        };
+        assertEquals(expected, process.exists(SOME_PID));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/ActivatorTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -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.common.portability.internal;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.ServiceRegistration;
+
+import com.redhat.thermostat.common.portability.UserNameUtil;
+import com.redhat.thermostat.shared.config.CommonPaths;
+import com.redhat.thermostat.shared.config.NativeLibraryResolver;
+import com.redhat.thermostat.testutils.StubBundleContext;
+import com.redhat.thermostat.common.portability.internal.linux.UserNameUtilImpl;
+
+public class ActivatorTest {
+
+    private StubBundleContext context;
+    private ServiceRegistration ipcReg;
+
+    @Before
+    public void setup() {
+        context = new StubBundleContext();
+        CommonPaths paths = mock(CommonPaths.class);
+        when(paths.getSystemNativeLibsRoot()).thenReturn(new File("target"));
+        when(paths.getUserAgentAuthConfigFile()).thenReturn(new File("not.exist.does.not.matter"));
+        NativeLibraryResolver.setCommonPaths(paths);
+    }
+
+    @Test
+    public void verifyServiceIsRegistered() throws Exception {
+        Activator activator = new Activator();
+        activator.start(context);
+
+        assertTrue(context.isServiceRegistered(UserNameUtil.class.getName(), UserNameUtilImpl.class));
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/SysConfTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,52 @@
+/*
+ * 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.common.portability.internal;
+
+import static org.junit.Assert.assertTrue;
+
+import com.redhat.thermostat.common.portability.SysConf;
+import org.junit.Test;
+
+public class SysConfTest {
+
+    @Test
+    public void test() {
+        long ticksPerSecond = SysConf.getClockTicksPerSecond();
+        assertTrue(ticksPerSecond >= 1);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/linux/LinuxProcessUserInfoBuilderImplTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -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.common.portability.internal.linux;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import com.redhat.thermostat.common.portability.UserNameLookupException;
+import com.redhat.thermostat.common.portability.UserNameUtil;
+import com.redhat.thermostat.common.portability.ProcessUserInfo;
+import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder;
+
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
+import org.junit.Test;
+
+import com.redhat.thermostat.common.tools.ApplicationException;
+
+public class LinuxProcessUserInfoBuilderImplTest {
+    
+    @Test
+    public void testBuild() throws UserNameLookupException, IOException, ApplicationException {
+        StringReader reader = new StringReader("Uid:   2000  2000  2000  2000");
+        ProcDataSource source = mock(ProcDataSource.class);
+        UserNameUtil util = mock(UserNameUtil.class);
+        when(util.getUserName(2000)).thenReturn("myUser");
+        when(source.getStatusReader(anyInt())).thenReturn(reader);
+        ProcessUserInfoBuilder builder = new LinuxProcessUserInfoBuilderImpl(source, util);
+        ProcessUserInfo info = builder.build(0);
+        
+        assertEquals(2000, info.getUid());
+        assertEquals("myUser", info.getUsername());
+    }
+    
+    @Test
+    public void testBuildErrorUid() throws IOException, ApplicationException {
+        StringReader reader = new StringReader("");
+        ProcDataSource source = mock(ProcDataSource.class);
+        UserNameUtil util = mock(UserNameUtil.class);
+        when(source.getStatusReader(anyInt())).thenReturn(reader);
+        ProcessUserInfoBuilder builder = new LinuxProcessUserInfoBuilderImpl(source, util);
+        ProcessUserInfo info = builder.build(0);
+        
+        assertEquals(-1, info.getUid());
+        assertEquals(null, info.getUsername());
+    }
+    
+    @Test
+    public void testBuildErrorUsername() throws IOException, UserNameLookupException, ApplicationException {
+        StringReader reader = new StringReader("Uid:   2000  2000  2000  2000");
+        ProcDataSource source = mock(ProcDataSource.class);
+        UserNameUtil util = mock(UserNameUtil.class);
+        when(util.getUserName(2000)).thenReturn(null);
+        when(source.getStatusReader(anyInt())).thenReturn(reader);
+        ProcessUserInfoBuilder builder = new LinuxProcessUserInfoBuilderImpl(source, util);
+        ProcessUserInfo info = builder.build(0);
+        
+        assertEquals(2000, info.getUid());
+        assertEquals(null, info.getUsername());
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImplTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -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.common.portability.internal.windows;
+
+import com.redhat.thermostat.shared.config.OS;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.util.Map;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * These tests are disabled until we get the DLL path issues sorted out
+ * TODO - These tests currently fail on Windows because the helper DLL isn't on the execution path
+ */
+
+@Ignore
+public class WindowsHelperImplTest {
+
+    @Test
+    public void loadNativeLib() {
+        Assume.assumeTrue(OS.IS_WINDOWS);
+        final WindowsHelperImpl impl = WindowsHelperImpl.INSTANCE;
+        Assert.assertNotNull(impl);
+    }
+
+    @Test
+    public void testGetHostInfo() {
+        Assume.assumeTrue(OS.IS_WINDOWS);
+        final WindowsHelperImpl impl = WindowsHelperImpl.INSTANCE;
+        Assert.assertNotNull(impl);
+        assertContainsData(impl.getHostName());
+        assertContainsData(impl.getOSName());
+        Assert.assertTrue(impl.getOSName().toLowerCase().contains("win"));
+        assertContainsData(impl.getOSVersion());
+        assertContainsData(impl.getCPUModel());
+        Assert.assertTrue(impl.getCPUCount() > 0);
+        Assert.assertTrue(impl.getTotalMemory() > 0);
+    }
+
+    @Test
+    @Ignore
+    public void testGetProcessInfo() {
+        Assume.assumeTrue(OS.IS_WINDOWS);
+        final WindowsHelperImpl impl = WindowsHelperImpl.INSTANCE;
+        Assert.assertNotNull(impl);
+        int pid = /*TODO: retrieve current process identifier*/0;
+        assertContainsData(impl.getUserName(pid));
+        Assert.assertTrue(impl.getUid(pid) >= 0);
+        Map<String,String> envMap = impl.getEnvironment(pid);
+        Assert.assertNotNull(envMap);
+        Assert.assertFalse(envMap.isEmpty());
+    }
+
+    private static void assertContainsData( final String s ) {
+        Assert.assertNotNull(s);
+        Assert.assertFalse(s.isEmpty());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/internal/windows/WindowsProcessUserInfoBuilderTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,102 @@
+/*
+ * 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.common.portability.internal.windows;
+
+import com.redhat.thermostat.common.portability.ProcessUserInfo;
+import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder;
+import com.redhat.thermostat.common.portability.PortableProcess;
+import com.redhat.thermostat.shared.config.OS;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+
+/**
+ * test windows user info builder
+ */
+public class WindowsProcessUserInfoBuilderTest {
+
+    private PortableProcess whelp;
+
+    private static final String FAKE_USERNAME = "testuser";
+    private static final int FAKE_PID = 4567;
+    private static final int FAKE_UID = 7652;
+
+    @Before
+    public void setup() {
+        whelp = Mockito.mock(PortableProcess.class);
+        Mockito.when(whelp.getUserName(Matchers.anyInt())).thenReturn("badname");
+        Mockito.when(whelp.getUserName(Matchers.eq(FAKE_PID))).thenReturn(FAKE_USERNAME);
+        Mockito.when(whelp.getUid(Matchers.anyInt())).thenReturn(11);
+        Mockito.when(whelp.getUid(Matchers.eq(FAKE_PID))).thenReturn(FAKE_UID);
+    }
+
+    // TODO - This test currently fails on Windows because the helper DLL isn't on the execution path
+    @Test
+    @Ignore
+    public void testSimpleBuild() {
+        Assume.assumeTrue(OS.IS_WINDOWS);
+        ProcessUserInfo info = new WindowsUserInfoBuilderImpl().build(FAKE_PID);
+        Assert.assertNotNull(info);
+    }
+
+    @Test
+    public void testGetInfoFromGoodPid() {
+        final ProcessUserInfoBuilder ib = new WindowsUserInfoBuilderImpl(whelp);
+        final ProcessUserInfo hi = ib.build(FAKE_PID);
+        assertEquals(FAKE_USERNAME, hi.getUsername());
+        assertEquals(FAKE_UID, hi.getUid());
+    }
+
+    @Test
+    public void testGetInfoFromBadPid() {
+        final ProcessUserInfoBuilder ib = new WindowsUserInfoBuilderImpl(whelp);
+        final ProcessUserInfo hi = ib.build(FAKE_PID+1);
+        Assert.assertNotSame(FAKE_USERNAME,hi.getUsername());
+        Assert.assertNotSame(FAKE_UID, hi.getUid());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/portability/src/test/java/com/redhat/thermostat/common/portability/linux/ProcDataSourceTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,114 @@
+/*
+ * 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.common.portability.linux;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
+import com.redhat.thermostat.shared.config.OS;
+import org.junit.Assume;
+import org.junit.Test;
+
+import com.redhat.thermostat.testutils.TestUtils;
+
+public class ProcDataSourceTest {
+
+    @Test
+    public void testGetCpuInfoReader() throws IOException {
+        Assume.assumeTrue(OS.IS_UNIX);
+        Reader r = new ProcDataSource().getCpuInfoReader();
+        assertNotNull(r);
+    }
+
+    @Test
+    public void testGetCpuLoadReader() throws IOException {
+        Assume.assumeTrue(OS.IS_UNIX);
+        Reader r = new ProcDataSource().getCpuLoadReader();
+        assertNotNull(r);
+    }
+
+    @Test
+    public void testGetMemInfoReader() throws IOException {
+        Assume.assumeTrue(OS.IS_UNIX);
+        Reader r = new ProcDataSource().getMemInfoReader();
+        assertNotNull(r);
+    }
+
+    @Test
+    public void testGetStatReader() throws IOException {
+        Assume.assumeTrue(OS.IS_UNIX);
+        int pid = TestUtils.getProcessId();
+        Reader r = new ProcDataSource().getStatReader(pid);
+        assertNotNull(r);
+    }
+
+    @Test
+    public void testGetEnvironReader() throws IOException {
+        Assume.assumeTrue(OS.IS_UNIX);
+        int pid = TestUtils.getProcessId();
+        Reader r = new ProcDataSource().getEnvironReader(pid);
+        assertNotNull(r);
+    }
+
+    @Test
+    public void testIoReader() throws Exception {
+        Assume.assumeTrue(OS.IS_UNIX);
+        int pid = TestUtils.getProcessId();
+        Reader r = new ProcDataSource().getIoReader(pid);
+        assertNotNull(r);
+    }
+
+    @Test
+    public void testStatReader() throws Exception {
+        Assume.assumeTrue(OS.IS_UNIX);
+        int pid = TestUtils.getProcessId();
+        Reader r = new ProcDataSource().getStatReader(pid);
+        assertNotNull(r);
+    }
+
+    @Test
+    public void testStatusReader() throws Exception {
+        Assume.assumeTrue(OS.IS_UNIX);
+        int pid = TestUtils.getProcessId();
+        Reader r = new ProcDataSource().getStatusReader(pid);
+        assertNotNull(r);
+    }
+}
+
--- a/distribution/assembly/core-assembly-windows.xml	Fri Jan 20 10:48:09 2017 -0500
+++ b/distribution/assembly/core-assembly-windows.xml	Mon Jan 23 10:11:31 2017 -0500
@@ -65,6 +65,7 @@
         <include>com.redhat.thermostat:thermostat-agent-ipc-tcpsocket-client</include>
         <include>com.redhat.thermostat:thermostat-common-core</include>
         <include>com.redhat.thermostat:thermostat-common-command</include>
+        <include>com.redhat.thermostat:thermostat-common-portability</include>
         <include>com.redhat.thermostat:thermostat-process-handler</include>
         <include>com.redhat.thermostat:thermostat-storage-cli</include>
         <include>com.redhat.thermostat:thermostat-storage-mongodb</include>
--- a/distribution/assembly/core-assembly.xml	Fri Jan 20 10:48:09 2017 -0500
+++ b/distribution/assembly/core-assembly.xml	Mon Jan 23 10:11:31 2017 -0500
@@ -67,6 +67,7 @@
         <include>com.redhat.thermostat:thermostat-agent-ipc-unixsocket-client</include>
         <include>com.redhat.thermostat:thermostat-common-core</include>
         <include>com.redhat.thermostat:thermostat-common-command</include>
+        <include>com.redhat.thermostat:thermostat-common-portability</include>
         <include>com.redhat.thermostat:thermostat-process-handler</include>
         <include>com.redhat.thermostat:thermostat-storage-cli</include>
         <include>com.redhat.thermostat:thermostat-storage-mongodb</include>
--- a/distribution/packaging/fedora/thermostat.spec	Fri Jan 20 10:48:09 2017 -0500
+++ b/distribution/packaging/fedora/thermostat.spec	Mon Jan 23 10:11:31 2017 -0500
@@ -573,8 +573,8 @@
     "<groupId>com.github.jnr</groupId>"
 
 # Don't use maven-exec-plugin. We do things manually in order to avoid this
-# additional dep. It's used in agent/core/pom.xml et.al.
-%pom_remove_plugin org.codehaus.mojo:exec-maven-plugin agent/core
+# additional dep. It's used in common/portability/pom.xml et.al.
+%pom_remove_plugin org.codehaus.mojo:exec-maven-plugin common/portability
 %pom_remove_plugin org.codehaus.mojo:exec-maven-plugin keyring
 %pom_remove_plugin org.codehaus.mojo:exec-maven-plugin laf-utils
 
@@ -694,6 +694,17 @@
            src/main/java/com/redhat/thermostat/common/internal/LocaleResources.java \
            src/main/java/com/redhat/thermostat/common/utils/LoggingUtils.java
 popd
+pushd common/portability
+  mkdir -p target/classes
+  javac -cp ../../config/target/classes:../../annotations/target/classes:../../common/core/target/classes \
+        -d target/classes \
+         src/main/java/com/redhat/thermostat/common/portability/HostName.java \
+         src/main/java/com/redhat/thermostat/common/portability/UserNameUtil.java \
+         src/main/java/com/redhat/thermostat/common/portability/UserNameLookupException.java \
+         src/main/java/com/redhat/thermostat/common/portability/internal/linux/UserNameUtilImpl.java
+         src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImpl.java
+  make all
+popd
 pushd keyring
   mkdir -p target/classes
   javac -cp ../config/target/classes:../annotations/target/classes \
@@ -705,17 +716,6 @@
   ./configure
   make all
 popd
-pushd agent/core
-  mkdir -p target/classes
-  javac -cp ../../config/target/classes:../../annotations/target/classes:../../common/core/target/classes \
-        -d target/classes \
-         src/main/java/com/redhat/thermostat/agent/utils/hostname/HostName.java \
-         src/main/java/com/redhat/thermostat/agent/utils/username/UserNameUtil.java \
-         src/main/java/com/redhat/thermostat/agent/utils/username/UserNameLookupException.java \
-         src/main/java/com/redhat/thermostat/agent/utils/windows/WindowsHelperImpl.java \
-         src/main/java/com/redhat/thermostat/utils/username/internal/UserNameUtilImpl.java
-  make all
-popd
 pushd laf-utils
   mkdir -p target/classes
   javac -cp ../config/target/classes \
--- a/distribution/pom.xml	Fri Jan 20 10:48:09 2017 -0500
+++ b/distribution/pom.xml	Mon Jan 23 10:11:31 2017 -0500
@@ -113,9 +113,9 @@
                   <target>
                     <copy file="${main.basedir}/keyring/target/libGnomeKeyringWrapper.so"
                           todir="${project.build.directory}/image/libs/native" />
-                    <copy file="${main.basedir}/agent/core/target/libHostNameWrapper.so"
+                    <copy file="${main.basedir}/common/portability/target/libHostNameWrapper.so"
                           todir="${project.build.directory}/image/libs/native" />
-                    <copy file="${main.basedir}/agent/core/target/libUserNameUtilWrapper.so"
+                    <copy file="${main.basedir}/common/portability/target/libUserNameUtilWrapper.so"
                           todir="${project.build.directory}/image/libs/native" />
                     <copy file="${main.basedir}/laf-utils/target/libGTKThemeUtils.so"
                           todir="${project.build.directory}/image/libs/native" />
@@ -169,11 +169,11 @@
                 <configuration>
                   <target>
                     <!--  copy and rename the native libraries -->
-                    <copy file="${main.basedir}/agent/core/target/HostNameWrapper.dll"
+                    <copy file="${main.basedir}/common/portability/target/HostNameWrapper.dll"
                           todir="${project.build.directory}/image/libs/native" />
-                    <copy file="${main.basedir}/agent/core/target/UserNameUtilWrapper.dll"
+                    <copy file="${main.basedir}/common/portability/target/UserNameUtilWrapper.dll"
                           todir="${project.build.directory}/image/libs/native" />
-                    <copy file="${main.basedir}/agent/core/target/WindowsHelperWrapper.dll"
+                    <copy file="${main.basedir}/common/portability/target/WindowsHelperWrapper.dll"
                           todir="${project.build.directory}/image/libs/native" />
                   </target>
                 </configuration>
@@ -587,6 +587,11 @@
       <version>${project.version}</version>
     </dependency>
     <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-portability</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
         <groupId>com.redhat.thermostat</groupId>
         <artifactId>thermostat-process-handler</artifactId>
         <version>${project.version}</version>
--- a/distribution/windows/scripts/thermostat-agent-proxy.cmd	Fri Jan 20 10:48:09 2017 -0500
+++ b/distribution/windows/scripts/thermostat-agent-proxy.cmd	Mon Jan 23 10:11:31 2017 -0500
@@ -1,6 +1,6 @@
 @echo off
 
-:: Copyright 2016 Red Hat, Inc.
+:: Copyright 2017 Red Hat, Inc.
 ::
 :: This file is part of Thermostat.
 ::
@@ -36,6 +36,55 @@
 
 setlocal
 
-%~dp0\thermostat-common.cmd
+if "%4"=="" goto usage
+if not "%5"=="" goto usage
+
+ goto skipfuncdefs
+
+ :usage
+   echo "usage: %~f0 <pidOfTargetJvm> <userNameOfJvmOwner> <ipcConfigFile> <ipcServerName>"
+   exit /b 1
+
+ :skipfuncdefs
+
+set TARGET_PID=%1
+set TARGET_USER=%2
+set CONFIG_FILE=%3
+set IPC_SERVER_NAME=%4
+
+:: Source thermostat-ipc-client-common from same directory as this script
+:: Defines IPC_CLASSPATH variable with JARs necessary for the IPC service
+
+call %~dp0\thermostat-ipc-client-common.cmd
+if not "%errorlevel%"=="0" exit /b %errorlevel%
 
-echo thermostat-agent-proxy not implemented on Windows.
+:: Ensure thermostat-ipc-client-common sourced correctly
+if not defined IPC_CLASSPATH (
+  echo "Classpath not properly defined for agent proxy"
+  exit /b 1
+)
+
+:: Need tools from the JVM
+set TOOLS_JAR=%JAVA_HOME%\lib\tools.jar
+
+:: Additional JARs necessary for the agent proxy
+set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\thermostat-common-core-@project.version@.jar
+set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\thermostat-shared-config-@project.version@.jar
+set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\thermostat-agent-proxy-server-@project.version@.jar
+set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\gson-@gson.version@.jar
+set IPC_CLASSPATH=%TOOLS_JAR%;%IPC_CLASSPATH%
+
+set AGENT_PROXY_CLASS=com.redhat.thermostat.agent.proxy.server.AgentProxy
+
+:: Set this to remote debug
+if defined THERMOSTAT_DEBUG (
+  set DEBUG_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=1082
+)
+
+:: Start server
+:: within the server, consider adjusting toek priviledge to disable debug, etc
+set CONFIG_FILE_ARG=-DipcConfigFile=%CONFIG_FILE%
+
+%JAVA% -cp %IPC_CLASSPATH% %CONFIG_FILE_ARG% %LOGGING_ARGS% %DEBUG_OPTS% %AGENT_PROXY_CLASS% %TARGET_PID% %IPC_SERVER_NAME% %TARGET_USER%
+
+
--- a/distribution/windows/scripts/thermostat-common.cmd	Fri Jan 20 10:48:09 2017 -0500
+++ b/distribution/windows/scripts/thermostat-common.cmd	Mon Jan 23 10:11:31 2017 -0500
@@ -1,6 +1,6 @@
 @echo off
 
-:: Copyright 2016 Red Hat, Inc.
+:: Copyright 2017 Red Hat, Inc.
 ::
 :: This file is part of Thermostat.
 ::
@@ -40,15 +40,15 @@
 
 :: Duplicated in ThermostatVmMainLabelDecorator
 set THERMOSTAT_MAIN=com.redhat.thermostat.main.Thermostat
+set jdk_home_candidate=@thermostat.jdk.home@
 
 if not defined JAVA_HOME (
-  set jdk_home_candidate="@thermostat.jdk.home@"
   if exist %jdk_home_candidate%\bin\javac.exe (
     set JAVA_HOME=%jdk_home_candidate%
   ) else (
-    :: Got likely a JRE, but thermostat expects a full JDK, try
-    :: one level up and hope this will work. We check
-    :: if JAVA_HOME is a valid value below.
+    rem Got likely a JRE, but thermostat expects a full JDK, try
+    rem one level up and hope this will work. We check
+    rem if JAVA_HOME is a valid value below.
     set JAVA_HOME=%jdk_home_candidate%\..
   )
 )
--- a/distribution/windows/scripts/thermostat-webservice.cmd	Fri Jan 20 10:48:09 2017 -0500
+++ b/distribution/windows/scripts/thermostat-webservice.cmd	Mon Jan 23 10:11:31 2017 -0500
@@ -1,6 +1,6 @@
 @echo off
 
-:: Copyright 2016 Red Hat, Inc.
+:: Copyright 2017 Red Hat, Inc.
 ::
 :: This file is part of Thermostat.
 ::
@@ -39,6 +39,7 @@
 %~dp0\thermostat-common.cmd
 
 echo thermostat-webservice not implemented on Windows.
+exit 1
 
 set TOMCAT_DIR=tomcat
 
--- a/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatBuilder.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatBuilder.java	Mon Jan 23 10:11:31 2017 -0500
@@ -41,7 +41,7 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
 import com.redhat.thermostat.common.Clock;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 import com.redhat.thermostat.host.cpu.common.model.CpuStat;
@@ -139,7 +139,7 @@
 
     private long[] getCurrentCpuTicksWindows() {
         long[] values = new long[1];
-        values[1] = clock.getMonotonicTimeNanos();
+        values[0] = clock.getMonotonicTimeNanos();
         return values;
     }
 
--- a/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/agent/internal/HostCpuBackend.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/host-cpu/agent/src/main/java/com/redhat/thermostat/host/cpu/agent/internal/HostCpuBackend.java	Mon Jan 23 10:11:31 2017 -0500
@@ -38,8 +38,8 @@
 
 import java.util.concurrent.ScheduledExecutorService;
 
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
-import com.redhat.thermostat.agent.utils.SysConf;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.SysConf;
 import com.redhat.thermostat.backend.HostPollingAction;
 import com.redhat.thermostat.backend.HostPollingBackend;
 import com.redhat.thermostat.common.Clock;
--- a/host-cpu/agent/src/test/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatBuilderTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/host-cpu/agent/src/test/java/com/redhat/thermostat/host/cpu/agent/internal/CpuStatBuilderTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -49,7 +49,7 @@
 
 import org.junit.Test;
 
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
 import com.redhat.thermostat.common.Clock;
 import com.redhat.thermostat.common.SystemClock;
 import com.redhat.thermostat.host.cpu.common.model.CpuStat;
--- a/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/agent/internal/HostMemoryBackend.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/agent/internal/HostMemoryBackend.java	Mon Jan 23 10:11:31 2017 -0500
@@ -38,7 +38,7 @@
 
 import java.util.concurrent.ScheduledExecutorService;
 
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
 import com.redhat.thermostat.backend.HostPollingAction;
 import com.redhat.thermostat.backend.HostPollingBackend;
 import com.redhat.thermostat.common.Version;
--- a/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatBuilder.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/host-memory/agent/src/main/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatBuilder.java	Mon Jan 23 10:11:31 2017 -0500
@@ -41,10 +41,10 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
-import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
 import com.redhat.thermostat.common.NotImplementedException;
 import com.redhat.thermostat.common.Size;
+import com.redhat.thermostat.common.portability.PortableMemoryStat;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 import com.redhat.thermostat.host.memory.common.model.MemoryStat;
 import com.redhat.thermostat.shared.config.OS;
@@ -130,7 +130,7 @@
     private MemoryStat buildFromWindows() {
         long timestamp = System.currentTimeMillis();
 
-        WindowsHelperImpl.MemoryStat memstat = new WindowsHelperImpl.MemoryStat();
+        PortableMemoryStat memstat = PortableMemoryStat.build();
 
         String wId = writerId.getWriterID();
         return new MemoryStat(wId, timestamp, memstat.getTotal(), memstat.getFree(), memstat.getBuffers(), memstat.getCached(), memstat.getSwapTotal(), memstat.getSwapFree(), memstat.getCommitLimit());
--- a/host-memory/agent/src/test/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatBuilderTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/host-memory/agent/src/test/java/com/redhat/thermostat/host/memory/agent/internal/MemoryStatBuilderTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -49,7 +49,7 @@
 import org.junit.Before;
 import org.junit.Test;
 
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
 import com.redhat.thermostat.host.memory.common.model.MemoryStat;
 import com.redhat.thermostat.storage.core.WriterID;
 
--- a/numa/agent/src/main/java/com/redhat/thermostat/numa/agent/internal/NumaWindowsCollectorImpl.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/numa/agent/src/main/java/com/redhat/thermostat/numa/agent/internal/NumaWindowsCollectorImpl.java	Mon Jan 23 10:11:31 2017 -0500
@@ -1,57 +1,57 @@
-/*
- * 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.numa.agent.internal;
-
-import com.redhat.thermostat.numa.common.NumaNodeStat;
-
-import java.io.IOException;
-
-public class NumaWindowsCollectorImpl implements NumaCollector {
-
-    @Override
-    public NumaNodeStat[] collectData() throws IOException {
-        final NumaNodeStat[] nsa = new NumaNodeStat[1];
-        final NumaNodeStat ns = new NumaNodeStat();
-        nsa[0] = ns;
-        return nsa;
-    }
-
-    @Override
-    public int getNumberOfNumaNodes() {
-        return 1;
-    }
-}
+/*
+ * 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.numa.agent.internal;
+
+import com.redhat.thermostat.numa.common.NumaNodeStat;
+
+import java.io.IOException;
+
+public class NumaWindowsCollectorImpl implements NumaCollector {
+
+    @Override
+    public NumaNodeStat[] collectData() throws IOException {
+        final NumaNodeStat[] nsa = new NumaNodeStat[1];
+        final NumaNodeStat ns = new NumaNodeStat();
+        nsa[0] = ns;
+        return nsa;
+    }
+
+    @Override
+    public int getNumberOfNumaNodes() {
+        return 1;
+    }
+}
--- a/process-handler/pom.xml	Fri Jan 20 10:48:09 2017 -0500
+++ b/process-handler/pom.xml	Mon Jan 23 10:11:31 2017 -0500
@@ -92,6 +92,12 @@
       <artifactId>thermostat-common-core</artifactId>
       <version>${project.version}</version>
     </dependency>
+
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-portability</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
   
 </project>
--- a/process-handler/src/main/java/com/redhat/thermostat/service/internal/ProcessUtilitiesBase.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/process-handler/src/main/java/com/redhat/thermostat/service/internal/ProcessUtilitiesBase.java	Mon Jan 23 10:11:31 2017 -0500
@@ -95,7 +95,7 @@
         try {
             rt.exec(command);
         } catch (IOException e) {
-            logger.log(Level.WARNING, "can't run kill!", e);
+            logger.log(Level.WARNING, "can't run '" + command + "'", e);
         }
     }
 
--- a/process-handler/src/main/java/com/redhat/thermostat/service/internal/windows/WindowsProcessUtilities.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/process-handler/src/main/java/com/redhat/thermostat/service/internal/windows/WindowsProcessUtilities.java	Mon Jan 23 10:11:31 2017 -0500
@@ -36,6 +36,7 @@
 
 package com.redhat.thermostat.service.internal.windows;
 
+import com.redhat.thermostat.common.portability.PortableProcessImpl;
 import com.redhat.thermostat.service.internal.ProcessUtilitiesBase;
 import com.redhat.thermostat.service.process.UNIXSignal;
 
@@ -73,8 +74,7 @@
 
     @Override
     public void sendSignal(Integer pid, UNIXSignal signal) {
-        // TODO - port to Windows
-        exec("kill -s " + signal.signalName() + " " + pid);
+        PortableProcessImpl.INSTANCE.terminateProcess(pid);
     }
 
 }
--- a/process-handler/src/test/java/com/redhat/thermostat/service/internal/windows/WindowsProcessUtilitiesTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/process-handler/src/test/java/com/redhat/thermostat/service/internal/windows/WindowsProcessUtilitiesTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -86,24 +86,6 @@
     }
 
     @Test
-    public void sendKillSignalTest() {
-
-        process.sendSignal(12345, UNIXSignal.KILL);
-
-        Assert.assertTrue(processArguments.contains("kill -s kill 12345"));
-        Assert.assertEquals(1, processArguments.size());
-    }
-
-    @Test
-    public void sendTermSignalTest() {
-
-        process.sendSignal(12345, UNIXSignal.TERM);
-
-        Assert.assertTrue(processArguments.contains("kill -s term 12345"));
-        Assert.assertEquals(1, processArguments.size());
-    }
-
-    @Test
     public void getProcessName() {
 
         String result = process.getProcessName(12345);
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/JvmStatHostListener.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/JvmStatHostListener.java	Mon Jan 23 10:11:31 2017 -0500
@@ -44,9 +44,9 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import com.redhat.thermostat.common.portability.ProcessUserInfo;
+import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder;
 import com.redhat.thermostat.backend.system.internal.models.InfoBuilderFactory;
-import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfo;
-import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder;
 import sun.jvmstat.monitor.MonitorException;
 import sun.jvmstat.monitor.MonitoredHost;
 import sun.jvmstat.monitor.MonitoredVm;
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/SystemBackend.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/SystemBackend.java	Mon Jan 23 10:11:31 2017 -0500
@@ -42,15 +42,15 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder;
 import com.redhat.thermostat.backend.system.internal.models.InfoBuilderFactory;
-import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder;
 
 import sun.jvmstat.monitor.HostIdentifier;
 import sun.jvmstat.monitor.MonitorException;
 import sun.jvmstat.monitor.MonitoredHost;
 
 import com.redhat.thermostat.agent.VmBlacklist;
-import com.redhat.thermostat.agent.utils.username.UserNameUtil;
+import com.redhat.thermostat.common.portability.UserNameUtil;
 import com.redhat.thermostat.backend.BaseBackend;
 import com.redhat.thermostat.common.Version;
 import com.redhat.thermostat.common.utils.LoggingUtils;
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/SystemBackendActivator.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/SystemBackendActivator.java	Mon Jan 23 10:11:31 2017 -0500
@@ -41,7 +41,7 @@
 import org.osgi.framework.ServiceRegistration;
 
 import com.redhat.thermostat.agent.VmBlacklist;
-import com.redhat.thermostat.agent.utils.username.UserNameUtil;
+import com.redhat.thermostat.common.portability.UserNameUtil;
 import com.redhat.thermostat.backend.Backend;
 import com.redhat.thermostat.backend.BackendService;
 import com.redhat.thermostat.common.MultipleServiceTracker;
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/HostInfoBuilderImpl.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/HostInfoBuilderImpl.java	Mon Jan 23 10:11:31 2017 -0500
@@ -43,8 +43,8 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
-import com.redhat.thermostat.agent.utils.hostname.HostName;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.HostName;
 import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder;
 import com.redhat.thermostat.common.Size;
 import com.redhat.thermostat.common.Size.Unit;
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/LinuxInfoBuilderFactory.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/LinuxInfoBuilderFactory.java	Mon Jan 23 10:11:31 2017 -0500
@@ -36,12 +36,14 @@
 
 package com.redhat.thermostat.backend.system.internal.linux;
 
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
-import com.redhat.thermostat.agent.utils.username.UserNameUtil;
+import com.redhat.thermostat.common.portability.ProcessUserInfo;
+import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder;
+
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.UserNameUtil;
 import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder;
 import com.redhat.thermostat.backend.system.internal.models.InfoBuilderFactory;
 import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder;
-import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder;
 import com.redhat.thermostat.storage.core.WriterID;
 
 /**
@@ -68,6 +70,6 @@
     }
 
     public ProcessUserInfoBuilder createProcessUserInfoBuilder(final UserNameUtil userNameUtil) {
-        return new ProcessUserInfoBuilderImpl(dataSource, userNameUtil);
+        return ProcessUserInfo.createBuilder(dataSource, userNameUtil);
     }
 }
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/ProcessEnvironmentBuilderImpl.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/ProcessEnvironmentBuilderImpl.java	Mon Jan 23 10:11:31 2017 -0500
@@ -46,7 +46,7 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
 import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/linux/ProcessUserInfoBuilderImpl.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +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.backend.system.internal.linux;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
-import com.redhat.thermostat.agent.utils.username.UserNameLookupException;
-import com.redhat.thermostat.agent.utils.username.UserNameUtil;
-import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfo;
-import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-
-class ProcessUserInfoBuilderImpl implements ProcessUserInfoBuilder {
-    
-    private static final ProcessUserInfo NON_EXISTENT_USER = new ProcessUserInfo();
-    private static final String PROC_STATUS_UID = "Uid:";
-    private static final Logger logger = LoggingUtils.getLogger(ProcessUserInfoBuilderImpl.class);
-    private ProcDataSource source;
-    private UserNameUtil userNameUtil;
-    
-    ProcessUserInfoBuilderImpl(ProcDataSource source, UserNameUtil userNameUtil) {
-        this.source = source;
-        this.userNameUtil = userNameUtil;
-    }
-
-    public ProcessUserInfo build(int pid) {
-        ProcessUserInfo info = NON_EXISTENT_USER;
-        try {
-            Reader reader = source.getStatusReader(pid);
-            long uid = getUidFromProcfs(new BufferedReader(reader));
-            String name = null;
-            try {
-                name = userNameUtil.getUserName(uid);
-            } catch (UserNameLookupException e) {
-                logger.log(Level.WARNING, "Unable to retrieve username for uid: " + uid, e);
-            }
-            info = new ProcessUserInfo(uid, name);
-        } catch (IOException e) {
-            logger.log(Level.WARNING, "Unable to read user info for " + pid, e);
-        }
-        
-        return info;
-    }
-
-    /*
-     * Look for the following line:
-     * Uid:  <RealUid>   <EffectiveUid>   <SavedUid>   <FSUid>
-     */
-    private long getUidFromProcfs(BufferedReader br) throws IOException {
-        long uid = -1;
-        String line;
-        while ((line = br.readLine()) != null) {
-            line = line.trim();
-            if (line.startsWith(PROC_STATUS_UID)) {
-                String[] parts = line.split("\\s+");
-                if (parts.length == 5) {
-                    try {
-                        // Use Real UID
-                        uid = Long.parseLong(parts[1]);
-                    } catch (NumberFormatException e) {
-                        throw new IOException("Unexpected output from ps command", e);
-                    }
-                }
-                else {
-                    throw new IOException("Expected 5 parts from split /proc/${pid}/status output, got " + parts.length);
-                }
-            }
-        }
-        if (uid < 0) {
-            throw new IOException("Unable to determine UID from /proc/${pid}/status");
-        }
-        return uid;
-    }
-
-
-}
-
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/models/InfoBuilderFactory.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/models/InfoBuilderFactory.java	Mon Jan 23 10:11:31 2017 -0500
@@ -36,7 +36,8 @@
 
 package com.redhat.thermostat.backend.system.internal.models;
 
-import com.redhat.thermostat.agent.utils.username.UserNameUtil;
+import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder;
+import com.redhat.thermostat.common.portability.UserNameUtil;
 import com.redhat.thermostat.backend.system.internal.linux.LinuxInfoBuilderFactory;
 import com.redhat.thermostat.backend.system.internal.windows.WindowsInfoBuilderFactory;
 import com.redhat.thermostat.shared.config.OS;
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/models/ProcessUserInfo.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +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.backend.system.internal.models;
-
-/**
- * Information about a system process (in Thermostat, these are JVM processes)
- */
-public class ProcessUserInfo {
-
-    private long uid;
-    private String username;
-
-    public ProcessUserInfo(long uid, String username) {
-        this.uid = uid;
-        this.username = username;
-    }
-
-    public ProcessUserInfo() {
-        this.uid = -1;
-        this.username = null;
-    }
-
-    public long getUid() {
-        return uid;
-    }
-
-    public String getUsername() {
-        return username;
-    }
-}
\ No newline at end of file
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/models/ProcessUserInfoBuilder.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +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.backend.system.internal.models;
-
-/**
- * Interface for ProcessUserInfo builders
- */
-public interface ProcessUserInfoBuilder {
-    ProcessUserInfo build(int pid);
-}
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsHostInfoBuilderImpl.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsHostInfoBuilderImpl.java	Mon Jan 23 10:11:31 2017 -0500
@@ -36,8 +36,9 @@
 
 package com.redhat.thermostat.backend.system.internal.windows;
 
-import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl;
+import com.redhat.thermostat.common.portability.PortableHost;
 import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder;
+import com.redhat.thermostat.common.portability.PortableHostImpl;
 import com.redhat.thermostat.storage.core.WriterID;
 import com.redhat.thermostat.storage.model.HostInfo;
 
@@ -47,26 +48,26 @@
 class WindowsHostInfoBuilderImpl implements HostInfoBuilder {
 
     private final WriterID writerID;
-    private final WindowsHelperImpl winHelper;
+    private final PortableHost helper;
 
     WindowsHostInfoBuilderImpl(final WriterID writerID) {
-        this(writerID, WindowsHelperImpl.INSTANCE);
+        this(writerID, PortableHostImpl.INSTANCE);
     }
 
-    WindowsHostInfoBuilderImpl(final WriterID writerID, WindowsHelperImpl winHelper) {
+    WindowsHostInfoBuilderImpl(final WriterID writerID, PortableHost helper) {
         this.writerID = writerID;
-        this.winHelper = winHelper;
+        this.helper = helper;
     }
 
     @Override
     public HostInfo build() {
         String wId = writerID.getWriterID();
         return new HostInfo(wId,
-                winHelper.getHostName(),
-                winHelper.getOSName(),
-                winHelper.getOSVersion(),
-                winHelper.getCPUModel(),
-                winHelper.getCPUCount(),
-                winHelper.getTotalMemory());
+                helper.getHostName(),
+                helper.getOSName(),
+                helper.getOSVersion(),
+                helper.getCPUModel(),
+                helper.getCPUCount(),
+                helper.getTotalMemory());
     }
 }
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsInfoBuilderFactory.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsInfoBuilderFactory.java	Mon Jan 23 10:11:31 2017 -0500
@@ -36,11 +36,12 @@
 
 package com.redhat.thermostat.backend.system.internal.windows;
 
-import com.redhat.thermostat.agent.utils.username.UserNameUtil;
+import com.redhat.thermostat.common.portability.ProcessUserInfo;
+import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder;
+import com.redhat.thermostat.common.portability.UserNameUtil;
 import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder;
 import com.redhat.thermostat.backend.system.internal.models.InfoBuilderFactory;
 import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder;
-import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder;
 import com.redhat.thermostat.storage.core.WriterID;
 
 /**
@@ -60,6 +61,6 @@
     }
 
     public ProcessUserInfoBuilder createProcessUserInfoBuilder(final UserNameUtil userNameUtil) {
-        return new WindowsUserInfoBuilderImpl();
+        return ProcessUserInfo.createBuilder(null, userNameUtil);
     }
 }
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsProcessEnvironmentBuilderImpl.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsProcessEnvironmentBuilderImpl.java	Mon Jan 23 10:11:31 2017 -0500
@@ -36,8 +36,9 @@
 
 package com.redhat.thermostat.backend.system.internal.windows;
 
-import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl;
 import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder;
+import com.redhat.thermostat.common.portability.PortableProcess;
+import com.redhat.thermostat.common.portability.PortableProcessImpl;
 
 import java.util.Map;
 
@@ -46,18 +47,18 @@
  */
 class WindowsProcessEnvironmentBuilderImpl implements ProcessEnvironmentBuilder {
 
-    private final WindowsHelperImpl winHelper;
+    private final PortableProcess helper;
 
     WindowsProcessEnvironmentBuilderImpl() {
-        this(WindowsHelperImpl.INSTANCE);
+        this(PortableProcessImpl.INSTANCE);
     }
 
-    WindowsProcessEnvironmentBuilderImpl(WindowsHelperImpl wh) {
-        winHelper = wh;
+    WindowsProcessEnvironmentBuilderImpl(PortableProcess wh) {
+        helper = wh;
     }
 
     @Override
     public Map<String, String> build(int pid) {
-        return winHelper.getEnvironment(pid);
+        return helper.getEnvironment(pid);
     }
 }
--- a/system-backend/src/main/java/com/redhat/thermostat/backend/system/internal/windows/WindowsUserInfoBuilderImpl.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +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.backend.system.internal.windows;
-
-import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl;
-import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfo;
-import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Build User information via Windows helper classes
- */
-class WindowsUserInfoBuilderImpl implements ProcessUserInfoBuilder {
-
-    private final WindowsHelperImpl winHelper;
-    private static final ProcessUserInfo NON_EXISTENT_USER = new ProcessUserInfo();
-    private static final Logger logger = LoggingUtils.getLogger(WindowsUserInfoBuilderImpl.class);
-
-    WindowsUserInfoBuilderImpl() {
-        this(WindowsHelperImpl.INSTANCE);
-    }
-
-    WindowsUserInfoBuilderImpl(WindowsHelperImpl winHelper) {
-        this.winHelper = winHelper;
-    }
-
-    @Override
-    public ProcessUserInfo build(int pid) {
-        ProcessUserInfo info = NON_EXISTENT_USER;
-        try {
-            final long uid = winHelper.getUid(pid);
-            final String name = winHelper.getUserName(pid);
-            info = new ProcessUserInfo(uid, name);
-        } catch (Exception e) {
-            logger.log(Level.WARNING, "Unable to read user info for " + pid, e);
-        }
-
-        return info;
-    }
-}
--- a/system-backend/src/main/native/WindowsHelperImpl.c	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*
- * Copyright 2012-2014 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.
- */
-
-#include "com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl.h"
-#include <jni.h>
-#include <unistd.h>
-#include <string.h>
-
-#if !defined(_WIN32)
-# include <netdb.h>
-#else // windows
-# include <winsock2.h>
-#endif
-
-#ifndef NI_MAXHOST
-#define NI_MAXHOST 1025
-#endif /* NI_MAXHOST */
-
-/*
- * Class:     com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl
- * Method:    getHostName0
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL
-Java_com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl_getHostName0
-  (JNIEnv *env, jclass winHelperClass)
-{
-      char hostname[NI_MAXHOST];
-      memset(hostname, 0, sizeof(hostname));
-
-      if (gethostname(hostname,  sizeof(hostname)) == 0) {
-          return (*env)->NewStringUTF(env, hostname);
-      }
-      return NULL;
-}
-
-/*
- * Class:     com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl
- * Method:    getUid0
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL
-Java_com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl_getUid0
-  (JNIEnv *env, jclass winHelperClass, jint pid)
-{
-    // TODO - implement this stub
-    return 987654321;
-}
-
-/*
- * Class:     com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl
- * Method:    getUserName0
- * Signature: (I)Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL
-Java_com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl_getUserName0
-  (JNIEnv *env, jclass winHelperClass, jint pid)
-{
-    // TODO - implement this stub
-    return (*env)->NewStringUTF(env, "(stub username)");
-}
-
-/*
- * Class:     com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl
- * Method:    getEnvironment0
- * Signature: ()[Ljava/lang/String;
- */
-JNIEXPORT jobjectArray JNICALL
-Java_com_redhat_thermostat_backend_system_internal_windows_WindowsHelperImpl_getEnvironment0
-  (JNIEnv *env, jclass winHelperClass, jint pid)
-{
-    // TODO - implement this stub
-    return NULL;
-}
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/JvmStatHostListenerTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/JvmStatHostListenerTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -56,14 +56,14 @@
 import java.util.Set;
 import java.util.UUID;
 
+import com.redhat.thermostat.common.portability.ProcessUserInfo;
+import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 
 import com.redhat.thermostat.agent.VmBlacklist;
 import com.redhat.thermostat.agent.VmStatusListener.Status;
-import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder;
-import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfo;
 import com.redhat.thermostat.storage.core.HostRef;
 import com.redhat.thermostat.storage.core.VmRef;
 import com.redhat.thermostat.storage.core.WriterID;
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/SystemBackendTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/SystemBackendTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -48,7 +48,7 @@
 import org.junit.Test;
 
 import com.redhat.thermostat.agent.VmBlacklist;
-import com.redhat.thermostat.agent.utils.username.UserNameUtil;
+import com.redhat.thermostat.common.portability.UserNameUtil;
 import com.redhat.thermostat.common.Version;
 import com.redhat.thermostat.storage.core.WriterID;
 import com.redhat.thermostat.storage.dao.HostInfoDAO;
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/HostInfoBuilderTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/HostInfoBuilderTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -51,7 +51,7 @@
 import org.junit.Before;
 import org.junit.Test;
 
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
 import com.redhat.thermostat.backend.system.internal.linux.HostInfoBuilderImpl.HostCpuInfo;
 import com.redhat.thermostat.backend.system.internal.linux.HostInfoBuilderImpl.HostMemoryInfo;
 import com.redhat.thermostat.backend.system.internal.linux.HostInfoBuilderImpl.HostOsInfo;
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/ProcessEnvironmentBuilderTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/ProcessEnvironmentBuilderTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -57,7 +57,7 @@
 import org.junit.Assume;
 import org.junit.Test;
 
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
 import com.redhat.thermostat.testutils.TestUtils;
 
 public class ProcessEnvironmentBuilderTest {
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/linux/ProcessUserInfoBuilderTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +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.backend.system.internal.linux;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.IOException;
-import java.io.StringReader;
-
-import org.junit.Test;
-
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
-import com.redhat.thermostat.agent.utils.username.UserNameLookupException;
-import com.redhat.thermostat.agent.utils.username.UserNameUtil;
-import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfo;
-import com.redhat.thermostat.common.tools.ApplicationException;
-
-public class ProcessUserInfoBuilderTest {
-    
-    @Test
-    public void testBuild() throws UserNameLookupException, IOException, ApplicationException {
-        StringReader reader = new StringReader("Uid:   2000  2000  2000  2000");
-        ProcDataSource source = mock(ProcDataSource.class);
-        UserNameUtil util = mock(UserNameUtil.class);
-        when(util.getUserName(2000)).thenReturn("myUser");
-        when(source.getStatusReader(anyInt())).thenReturn(reader);
-        ProcessUserInfoBuilderImpl builder = new ProcessUserInfoBuilderImpl(source, util);
-        ProcessUserInfo info = builder.build(0);
-        
-        assertEquals(2000, info.getUid());
-        assertEquals("myUser", info.getUsername());
-    }
-    
-    @Test
-    public void testBuildErrorUid() throws IOException, ApplicationException {
-        StringReader reader = new StringReader("");
-        ProcDataSource source = mock(ProcDataSource.class);
-        UserNameUtil util = mock(UserNameUtil.class);
-        when(source.getStatusReader(anyInt())).thenReturn(reader);
-        ProcessUserInfoBuilderImpl builder = new ProcessUserInfoBuilderImpl(source, util);
-        ProcessUserInfo info = builder.build(0);
-        
-        assertEquals(-1, info.getUid());
-        assertEquals(null, info.getUsername());
-    }
-    
-    @Test
-    public void testBuildErrorUsername() throws IOException, UserNameLookupException, ApplicationException {
-        StringReader reader = new StringReader("Uid:   2000  2000  2000  2000");
-        ProcDataSource source = mock(ProcDataSource.class);
-        UserNameUtil util = mock(UserNameUtil.class);
-        when(util.getUserName(2000)).thenReturn(null);
-        when(source.getStatusReader(anyInt())).thenReturn(reader);
-        ProcessUserInfoBuilderImpl builder = new ProcessUserInfoBuilderImpl(source, util);
-        ProcessUserInfo info = builder.build(0);
-        
-        assertEquals(2000, info.getUid());
-        assertEquals(null, info.getUsername());
-    }
-
-}
-
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsHostInfoBuilderTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsHostInfoBuilderTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -36,7 +36,7 @@
 
 package com.redhat.thermostat.backend.system.internal.windows;
 
-import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl;
+import com.redhat.thermostat.common.portability.PortableHost;
 import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder;
 import com.redhat.thermostat.shared.config.OS;
 import com.redhat.thermostat.storage.core.WriterID;
@@ -54,18 +54,18 @@
 public class WindowsHostInfoBuilderTest {
 
     private WriterID writerId;
-    private WindowsHelperImpl whelp;
+    private PortableHost helper;
 
     @Before
     public void setup() {
         writerId = mock(WriterID.class);
-        whelp = mock(WindowsHelperImpl.class);
-        when(whelp.getHostName()).thenReturn("testhost");
-        when(whelp.getOSName()).thenReturn("testos");
-        when(whelp.getOSVersion()).thenReturn("testversion");
-        when(whelp.getCPUModel()).thenReturn("testcpu");
-        when(whelp.getCPUCount()).thenReturn(4567);
-        when(whelp.getTotalMemory()).thenReturn(9876L);
+        helper = mock(PortableHost.class);
+        when(helper.getHostName()).thenReturn("testhost");
+        when(helper.getOSName()).thenReturn("testos");
+        when(helper.getOSVersion()).thenReturn("testversion");
+        when(helper.getCPUModel()).thenReturn("testcpu");
+        when(helper.getCPUCount()).thenReturn(4567);
+        when(helper.getTotalMemory()).thenReturn(9876L);
     }
 
     // TODO - This test currently fails on Windows because the helper DLL isn't on the execution path
@@ -79,7 +79,7 @@
 
     @Test
     public void testGetInfo() {
-        final HostInfoBuilder ib = new WindowsHostInfoBuilderImpl(writerId, whelp);
+        final HostInfoBuilder ib = new WindowsHostInfoBuilderImpl(writerId, helper);
         final HostInfo hi = ib.build();
         assertEquals("testhost",hi.getHostname());
         assertEquals("testos", hi.getOsName());
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsInfoBuilderFactoryTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsInfoBuilderFactoryTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -39,7 +39,6 @@
 import com.redhat.thermostat.backend.system.internal.models.HostInfoBuilder;
 import com.redhat.thermostat.backend.system.internal.models.InfoBuilderFactory;
 import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder;
-import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder;
 import org.junit.Test;
 
 import static org.junit.Assert.assertNotNull;
@@ -62,12 +61,4 @@
         assertNotNull(hib);
         assertTrue(hib instanceof WindowsProcessEnvironmentBuilderImpl);
     }
-
-    @Test
-    public void testCreateProcessUserInfoBuilder() {
-        final InfoBuilderFactory builder = new WindowsInfoBuilderFactory();
-        final ProcessUserInfoBuilder hib = builder.createProcessUserInfoBuilder(null);
-        assertNotNull(hib);
-        assertTrue(hib instanceof WindowsUserInfoBuilderImpl);
-    }
 }
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsProcessEnvironmentBuilderTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsProcessEnvironmentBuilderTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -36,7 +36,7 @@
 
 package com.redhat.thermostat.backend.system.internal.windows;
 
-import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl;
+import com.redhat.thermostat.common.portability.PortableProcess;
 import com.redhat.thermostat.backend.system.internal.models.ProcessEnvironmentBuilder;
 import com.redhat.thermostat.shared.config.OS;
 
@@ -62,7 +62,7 @@
  */
 public class WindowsProcessEnvironmentBuilderTest {
 
-    private WindowsHelperImpl whelp;
+    private PortableProcess whelp;
 
     private static final int FAKE_PID = 4567;
     private static final String PATH_KEY = "PATH";
@@ -72,7 +72,7 @@
 
     @Before
     public void setup() {
-        whelp = mock(WindowsHelperImpl.class);
+        whelp = mock(PortableProcess.class);
         goodMap.put(PATH_KEY, FAKE_PATH);
         when(whelp.getEnvironment(anyInt())).thenReturn(null);
         when(whelp.getEnvironment(eq(FAKE_PID))).thenReturn(goodMap);
--- a/system-backend/src/test/java/com/redhat/thermostat/backend/system/internal/windows/WindowsProcessUserInfoBuilderTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ /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.backend.system.internal.windows;
-
-import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl;
-import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfo;
-import com.redhat.thermostat.backend.system.internal.models.ProcessUserInfoBuilder;
-import com.redhat.thermostat.shared.config.OS;
-
-import org.junit.Assume;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-/**
- * test windows user info builder
- */
-public class WindowsProcessUserInfoBuilderTest {
-
-    private WindowsHelperImpl whelp;
-
-    private static final String FAKE_USERNAME = "testuser";
-    private static final int FAKE_PID = 4567;
-    private static final int FAKE_UID = 7652;
-
-    @Before
-    public void setup() {
-        whelp = mock(WindowsHelperImpl.class);
-        when(whelp.getUserName(anyInt())).thenReturn("badname");
-        when(whelp.getUserName(eq(FAKE_PID))).thenReturn(FAKE_USERNAME);
-        when(whelp.getUid(anyInt())).thenReturn(11);
-        when(whelp.getUid(eq(FAKE_PID))).thenReturn(FAKE_UID);
-    }
-
-    // TODO - This test currently fails on Windows because the helper DLL isn't on the execution path
-    @Test
-    @Ignore
-    public void testSimpleBuild() {
-        Assume.assumeTrue(OS.IS_WINDOWS);
-        ProcessUserInfo info = new WindowsUserInfoBuilderImpl().build(FAKE_PID);
-        assertNotNull(info);
-    }
-
-    @Test
-    public void testGetInfoFromGoodPid() {
-        final ProcessUserInfoBuilder ib = new WindowsUserInfoBuilderImpl(whelp);
-        final ProcessUserInfo hi = ib.build(FAKE_PID);
-        assertEquals(FAKE_USERNAME, hi.getUsername());
-        assertEquals(FAKE_UID, hi.getUid());
-    }
-
-    @Test
-    public void testGetInfoFromBadPid() {
-        final ProcessUserInfoBuilder ib = new WindowsUserInfoBuilderImpl(whelp);
-        final ProcessUserInfo hi = ib.build(FAKE_PID+1);
-        assertNotSame(FAKE_USERNAME,hi.getUsername());
-        assertNotSame(FAKE_UID, hi.getUid());
-    }
-}
--- a/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManager.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManager.java	Mon Jan 23 10:11:31 2017 -0500
@@ -49,12 +49,13 @@
 
 import org.jboss.byteman.agent.submit.Submit;
 
+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.shared.config.CommonPaths;
 import com.redhat.thermostat.storage.core.VmId;
 import com.redhat.thermostat.storage.core.WriterID;
-import com.redhat.thermostat.vm.byteman.agent.internal.ProcessUserInfoBuilder.ProcessUserInfo;
 import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO;
 import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus;
 
@@ -90,8 +91,8 @@
     }
     
     // for testing only
-    BytemanAgentAttachManager(BytemanAttacher attacher, IPCEndpointsManager ipcManager, VmBytemanDAO vmBytemanDao, SubmitHelper submit, 
-            WriterID writerId, ProcessUserInfoBuilder userInfoBuilder, FileSystemUtils fsUtils) {
+    BytemanAgentAttachManager(BytemanAttacher attacher, IPCEndpointsManager ipcManager, VmBytemanDAO vmBytemanDao, SubmitHelper submit,
+                              WriterID writerId, ProcessUserInfoBuilder userInfoBuilder, FileSystemUtils fsUtils) {
         this.attacher = attacher;
         this.ipcManager = ipcManager;
         this.vmBytemanDao = vmBytemanDao;
--- a/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacher.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacher.java	Mon Jan 23 10:11:31 2017 -0500
@@ -49,7 +49,7 @@
 import org.jboss.byteman.agent.install.Install;
 
 import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
-import com.redhat.thermostat.agent.utils.ProcessChecker;
+import com.redhat.thermostat.common.portability.ProcessChecker;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 import com.sun.tools.attach.AgentInitializationException;
 import com.sun.tools.attach.AgentLoadException;
--- a/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiver.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanRequestReceiver.java	Mon Jan 23 10:11:31 2017 -0500
@@ -44,6 +44,8 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import com.redhat.thermostat.common.portability.ProcessUserInfo;
+import com.redhat.thermostat.common.portability.ProcessUserInfoBuilder;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Reference;
@@ -53,8 +55,8 @@
 
 import com.redhat.thermostat.agent.command.RequestReceiver;
 import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
-import com.redhat.thermostat.agent.utils.username.UserNameUtil;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
+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;
@@ -154,7 +156,7 @@
     }
     
     protected void bindUserNameUtil(UserNameUtil userNameUtil) {
-        ProcessUserInfoBuilder userInfoBuilder = new ProcessUserInfoBuilder(new ProcDataSource(), userNameUtil);
+        ProcessUserInfoBuilder userInfoBuilder = ProcessUserInfo.createBuilder(new ProcDataSource(), userNameUtil);
         attachManager.setUserInfoBuilder(userInfoBuilder);
     }
     
--- a/vm-byteman/agent/src/main/java/com/redhat/thermostat/vm/byteman/agent/internal/ProcessUserInfoBuilder.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +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.agent.internal;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
-import com.redhat.thermostat.agent.utils.username.UserNameLookupException;
-import com.redhat.thermostat.agent.utils.username.UserNameUtil;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-
-/*
- * FIXME: This class was copied from system-backend.
- * Replace when this information is available from an API.
- */
-class ProcessUserInfoBuilder {
-    
-    private static final ProcessUserInfo NON_EXISTENT_USER = new ProcessUserInfo();
-    private static final String PROC_STATUS_UID = "Uid:";
-    private static final Logger logger = LoggingUtils.getLogger(ProcessUserInfoBuilder.class);
-    private ProcDataSource source;
-    private UserNameUtil userNameUtil;
-    
-    ProcessUserInfoBuilder(ProcDataSource source, UserNameUtil userNameUtil) {
-        this.source = source;
-        this.userNameUtil = userNameUtil;
-    }
-    
-    static class ProcessUserInfo {
-        
-        private long uid;
-        private String username;
-        
-        ProcessUserInfo(long uid, String username) {
-            this.uid = uid;
-            this.username = username;
-        }
-        
-        ProcessUserInfo() {
-            this.uid = -1;
-            this.username = null;
-        }
-        
-        public long getUid() {
-            return uid;
-        }
-        
-        public String getUsername() {
-            return username;
-        }
-    }
-    
-    ProcessUserInfo build(int pid) {
-        ProcessUserInfo info = NON_EXISTENT_USER;
-        try {
-            Reader reader = source.getStatusReader(pid);
-            long uid = getUidFromProcfs(new BufferedReader(reader));
-            String name = null;
-            try {
-                name = userNameUtil.getUserName(uid);
-            } catch (UserNameLookupException e) {
-                logger.log(Level.WARNING, "Unable to retrieve username for uid: " + uid, e);
-            }
-            info = new ProcessUserInfo(uid, name);
-        } catch (IOException e) {
-            logger.log(Level.WARNING, "Unable to read user info for " + pid, e);
-        }
-        
-        return info;
-    }
-
-    /*
-     * Look for the following line:
-     * Uid:  <RealUid>   <EffectiveUid>   <SavedUid>   <FSUid>
-     */
-    private long getUidFromProcfs(BufferedReader br) throws IOException {
-        long uid = -1;
-        String line;
-        while ((line = br.readLine()) != null) {
-            line = line.trim();
-            if (line.startsWith(PROC_STATUS_UID)) {
-                String[] parts = line.split("\\s+");
-                if (parts.length == 5) {
-                    try {
-                        // Use Real UID
-                        uid = Long.parseLong(parts[1]);
-                    } catch (NumberFormatException e) {
-                        throw new IOException("Unexpected output from ps command", e);
-                    }
-                }
-                else {
-                    throw new IOException("Expected 5 parts from split /proc/${pid}/status output, got " + parts.length);
-                }
-            }
-        }
-        if (uid < 0) {
-            throw new IOException("Unable to determine UID from /proc/${pid}/status");
-        }
-        return uid;
-    }
-
-
-}
-
--- a/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManagerTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAgentAttachManagerTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -63,13 +63,14 @@
 
 import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
 import com.redhat.thermostat.agent.ipc.server.ThermostatIPCCallbacks;
-import com.redhat.thermostat.agent.utils.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.storage.core.WriterID;
 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.agent.internal.ProcessUserInfoBuilder.ProcessUserInfo;
 import com.redhat.thermostat.vm.byteman.common.VmBytemanDAO;
 import com.redhat.thermostat.vm.byteman.common.VmBytemanStatus;
 
--- a/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacherTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/vm-byteman/agent/src/test/java/com/redhat/thermostat/vm/byteman/agent/internal/BytemanAttacherTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -56,7 +56,7 @@
 import org.mockito.ArgumentCaptor;
 
 import com.redhat.thermostat.agent.ipc.server.AgentIPCService;
-import com.redhat.thermostat.agent.utils.ProcessChecker;
+import com.redhat.thermostat.common.portability.ProcessChecker;
 import com.redhat.thermostat.vm.byteman.agent.internal.BytemanAttacher.BtmInstallHelper;
 import com.redhat.thermostat.vm.byteman.agent.internal.BytemanAttacher.InstallResult;
 
--- a/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/LinuxProcessStatusInfoBuilderImpl.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/LinuxProcessStatusInfoBuilderImpl.java	Mon Jan 23 10:11:31 2017 -0500
@@ -36,7 +36,7 @@
 
 package com.redhat.thermostat.vm.cpu.agent.internal;
 
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 
 import java.io.BufferedReader;
--- a/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/VmCpuBackend.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/VmCpuBackend.java	Mon Jan 23 10:11:31 2017 -0500
@@ -43,14 +43,14 @@
 import java.util.logging.Logger;
 
 import com.redhat.thermostat.agent.VmStatusListenerRegistrar;
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
-import com.redhat.thermostat.agent.utils.SysConf;
-import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.SysConf;
 import com.redhat.thermostat.backend.VmPollingAction;
 import com.redhat.thermostat.backend.VmPollingBackend;
 import com.redhat.thermostat.common.Clock;
 import com.redhat.thermostat.common.SystemClock;
 import com.redhat.thermostat.common.Version;
+import com.redhat.thermostat.common.portability.PortableHostImpl;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 import com.redhat.thermostat.shared.config.OS;
 import com.redhat.thermostat.storage.core.WriterID;
@@ -114,7 +114,7 @@
         }
 
         private int getWindowsCpuCount() {
-            return WindowsHelperImpl.INSTANCE.getCPUCount();
+            return PortableHostImpl.INSTANCE.getCPUCount();
         }
 
         private int getLinuxCpuCount(ProcDataSource dataSource) {
--- a/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/WindowsProcessStatusInfoBuilderImpl.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/vm-cpu/agent/src/main/java/com/redhat/thermostat/vm/cpu/agent/internal/WindowsProcessStatusInfoBuilderImpl.java	Mon Jan 23 10:11:31 2017 -0500
@@ -36,29 +36,22 @@
 
 package com.redhat.thermostat.vm.cpu.agent.internal;
 
-import com.redhat.thermostat.agent.utils.windows.WindowsHelperImpl;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-
-import java.util.logging.Logger;
+import com.redhat.thermostat.common.portability.PortableProcessImpl;
+import com.redhat.thermostat.common.portability.PortableProcessStat;
 
 /**
  * Extract status information about the process
  */
 public class WindowsProcessStatusInfoBuilderImpl implements ProcessStatusInfoBuilder {
 
-    //private static final Logger logger = LoggingUtils.getLogger(WindowsProcessStatusInfoBuilderImpl.class);
-
     WindowsProcessStatusInfoBuilderImpl() {
     }
 
     public ProcessStatusInfo build(int pid) {
 
-        final long[] info =  WindowsHelperImpl.INSTANCE.getProcessCPUInfo(pid);
+        final PortableProcessStat info =  PortableProcessImpl.INSTANCE.getProcessStat(pid);
 
-        final long utime = info[1];
-        final long stime = info[2];
-
-        return new ProcessStatusInfo(pid, utime, stime);
+        return new ProcessStatusInfo(pid, info.getUserTime(), info.getKernelTime());
     }
 
 }
--- a/vm-cpu/agent/src/test/java/com/redhat/thermostat/vm/cpu/agent/internal/LinuxProcessStatusInfoBuilderTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/vm-cpu/agent/src/test/java/com/redhat/thermostat/vm/cpu/agent/internal/LinuxProcessStatusInfoBuilderTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -48,7 +48,7 @@
 
 import org.junit.Test;
 
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
 
 public class LinuxProcessStatusInfoBuilderTest {
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/LinuxVmIoStatBuilder.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,65 @@
+/*
+ * 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.io.agent.internal;
+
+import com.redhat.thermostat.common.Clock;
+import com.redhat.thermostat.storage.core.WriterID;
+import com.redhat.thermostat.vm.io.common.VmIoStat;
+
+public class LinuxVmIoStatBuilder implements VmIoStatBuilder {
+
+    private final Clock clock;
+    private final ProcIoDataReader ioReader;
+    private final String writerId;
+
+    LinuxVmIoStatBuilder(Clock clock, ProcIoDataReader ioReader, WriterID writerId) {
+        this.clock = clock;
+        this.ioReader = ioReader;
+
+        this.writerId = writerId.getWriterID();
+    }
+
+    public synchronized VmIoStat build(String vmId, Integer pid) {
+        ProcIoData data = ioReader.read(pid);
+        if (data == null) {
+            return null;
+        }
+        long miliTime = clock.getRealTimeMillis();
+        return new VmIoStat(writerId, vmId, miliTime, data.rchar, data.wchar, data.syscr, data.syscw);
+    }
+
+}
--- a/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/ProcIoDataReader.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/ProcIoDataReader.java	Mon Jan 23 10:11:31 2017 -0500
@@ -41,7 +41,7 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 
 /**
--- a/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoBackend.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoBackend.java	Mon Jan 23 10:11:31 2017 -0500
@@ -37,12 +37,13 @@
 package com.redhat.thermostat.vm.io.agent.internal;
 
 import com.redhat.thermostat.agent.VmStatusListenerRegistrar;
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
 import com.redhat.thermostat.backend.VmListenerBackend;
 import com.redhat.thermostat.backend.VmUpdate;
 import com.redhat.thermostat.backend.VmUpdateListener;
 import com.redhat.thermostat.common.Clock;
 import com.redhat.thermostat.common.Version;
+import com.redhat.thermostat.shared.config.OS;
 import com.redhat.thermostat.storage.core.WriterID;
 import com.redhat.thermostat.vm.io.common.Constants;
 import com.redhat.thermostat.vm.io.common.VmIoStat;
@@ -58,7 +59,8 @@
             VmStatusListenerRegistrar registrar, WriterID writerId) {
         this(version,
                 vmIoStatDao,
-                new VmIoStatBuilder(clock, new ProcIoDataReader(new ProcDataSource()), writerId),
+                OS.IS_LINUX ? new LinuxVmIoStatBuilder(clock, new ProcIoDataReader(new ProcDataSource()), writerId)
+                        : new WindowsVmIoStatBuilder(clock, writerId),
                 registrar, writerId);
     }
 
--- a/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatBuilder.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatBuilder.java	Mon Jan 23 10:11:31 2017 -0500
@@ -36,30 +36,8 @@
 
 package com.redhat.thermostat.vm.io.agent.internal;
 
-import com.redhat.thermostat.common.Clock;
-import com.redhat.thermostat.storage.core.WriterID;
 import com.redhat.thermostat.vm.io.common.VmIoStat;
 
-public class VmIoStatBuilder {
-
-    private final Clock clock;
-    private final ProcIoDataReader ioReader;
-    private final String writerId;
-
-    public VmIoStatBuilder(Clock clock, ProcIoDataReader ioReader, WriterID writerId) {
-        this.clock = clock;
-        this.ioReader = ioReader;
-
-        this.writerId = writerId.getWriterID();
-    }
-
-    public synchronized VmIoStat build(String vmId, Integer pid) {
-        ProcIoData data = ioReader.read(pid);
-        if (data == null) {
-            return null;
-        }
-        long miliTime = clock.getRealTimeMillis();
-        return new VmIoStat(writerId, vmId, miliTime, data.rchar, data.wchar, data.syscr, data.syscw);
-    }
-
+public interface VmIoStatBuilder {
+    VmIoStat build(String vmId, Integer pid);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-io/agent/src/main/java/com/redhat/thermostat/vm/io/agent/internal/WindowsVmIoStatBuilder.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,60 @@
+/*
+ * 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.io.agent.internal;
+
+import com.redhat.thermostat.common.Clock;
+import com.redhat.thermostat.common.portability.PortableVmIoStat;
+import com.redhat.thermostat.storage.core.WriterID;
+import com.redhat.thermostat.vm.io.common.VmIoStat;
+
+public class WindowsVmIoStatBuilder implements VmIoStatBuilder {
+
+    private final Clock clock;
+    private final String writerId;
+
+    WindowsVmIoStatBuilder(Clock clock, WriterID writerId) {
+        this.clock = clock;
+        this.writerId = writerId.getWriterID();
+    }
+
+    public synchronized VmIoStat build(String vmId, Integer pid) {
+
+        PortableVmIoStat data = PortableVmIoStat.build(clock, pid);
+        return new VmIoStat(writerId, vmId, data.getTimeStamp(), data.getCharactersRead(), data.getCharactersWritten(), data.getReadSyscalls(), data.getWriteSyscalls());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/LinuxVmIoStatBuilderTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,100 @@
+/*
+ * 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.io.agent.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.redhat.thermostat.common.Clock;
+import com.redhat.thermostat.storage.core.WriterID;
+import com.redhat.thermostat.vm.io.common.VmIoStat;
+
+public class LinuxVmIoStatBuilderTest {
+
+    private WriterID writerID;
+
+    @Before
+    public void setup() {
+        writerID = mock(WriterID.class);
+    }
+
+    @Test
+    public void testBuilderBuildsNullForUnknownPid() {
+        Clock clock = mock(Clock.class);
+        ProcIoDataReader procDataReader = mock(ProcIoDataReader.class);
+        LinuxVmIoStatBuilder builder = new LinuxVmIoStatBuilder(clock, procDataReader, writerID);
+        VmIoStat result = builder.build("vmId", 0);
+        assertNull(result);
+    }
+
+    @Test
+    public void testBuildWithSufficientInformation() {
+        final int PID = 0;
+
+        int rchar = 1;
+        int wchar = 2;
+        int syscr = 3;
+        int syscw = 4;
+        int read_bytes = 5;
+        int write_bytes = 6;
+        int cancelled_write_bytes = 7;
+
+        final ProcIoData data = new ProcIoData(rchar, wchar, syscr, syscw,
+                read_bytes, write_bytes, cancelled_write_bytes);
+
+        ProcIoDataReader ioReader = mock(ProcIoDataReader.class);
+        when(ioReader.read(PID)).thenReturn(data);
+        Clock clock = mock(Clock.class);
+
+        LinuxVmIoStatBuilder builder = new LinuxVmIoStatBuilder(clock, ioReader, writerID);
+
+        VmIoStat ioData = builder.build("vmId", PID);
+        assertNotNull(ioData);
+        assertEquals(rchar, ioData.getCharactersRead());
+        assertEquals(wchar, ioData.getCharactersWritten());
+        assertEquals(syscr, ioData.getReadSyscalls());
+        assertEquals(syscw, ioData.getWriteSyscalls());
+    }
+
+}
+
--- a/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/ProcIoDataReaderTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/ProcIoDataReaderTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -44,7 +44,7 @@
 
 import org.junit.Test;
 
-import com.redhat.thermostat.agent.utils.linux.ProcDataSource;
+import com.redhat.thermostat.common.portability.linux.ProcDataSource;
 
 public class ProcIoDataReaderTest {
 
--- a/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/VmIoBackendTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ b/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/VmIoBackendTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -40,28 +40,18 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isA;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
+import com.redhat.thermostat.shared.config.OS;
 import org.junit.Before;
 import org.junit.Test;
-import org.mockito.ArgumentCaptor;
 
-import com.redhat.thermostat.agent.VmStatusListener.Status;
 import com.redhat.thermostat.agent.VmStatusListenerRegistrar;
-import com.redhat.thermostat.common.Clock;
 import com.redhat.thermostat.common.Ordered;
 import com.redhat.thermostat.common.Version;
 import com.redhat.thermostat.storage.core.WriterID;
-import com.redhat.thermostat.vm.io.common.VmIoStat;
 import com.redhat.thermostat.vm.io.common.VmIoStatDAO;
 
 public class VmIoBackendTest {
@@ -81,7 +71,7 @@
         registrar = mock(VmStatusListenerRegistrar.class);
 
         WriterID id = mock(WriterID.class);
-        ioStatBuilder = mock(VmIoStatBuilder.class);
+        ioStatBuilder = OS.IS_LINUX ? mock(LinuxVmIoStatBuilder.class) : mock(WindowsVmIoStatBuilder.class);
         backend = new VmIoBackend(version, vmIoStatDao, ioStatBuilder, registrar, id);
     }
 
--- a/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/VmIoStatBuilderTest.java	Fri Jan 20 10:48:09 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +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.io.agent.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import com.redhat.thermostat.common.Clock;
-import com.redhat.thermostat.storage.core.WriterID;
-import com.redhat.thermostat.vm.io.common.VmIoStat;
-
-public class VmIoStatBuilderTest {
-
-    private WriterID writerID;
-
-    @Before
-    public void setup() {
-        writerID = mock(WriterID.class);
-    }
-
-    @Test
-    public void testBuilderBuildsNullForUnknownPid() {
-        Clock clock = mock(Clock.class);
-        ProcIoDataReader procDataReader = mock(ProcIoDataReader.class);
-        VmIoStatBuilder builder = new VmIoStatBuilder(clock, procDataReader, writerID);
-        VmIoStat result = builder.build("vmId", 0);
-        assertNull(result);
-    }
-
-    @Test
-    public void testBuildWithSufficientInformation() {
-        final int PID = 0;
-
-        int rchar = 1;
-        int wchar = 2;
-        int syscr = 3;
-        int syscw = 4;
-        int read_bytes = 5;
-        int write_bytes = 6;
-        int cancelled_write_bytes = 7;
-
-        final ProcIoData data = new ProcIoData(rchar, wchar, syscr, syscw,
-                read_bytes, write_bytes, cancelled_write_bytes);
-
-        ProcIoDataReader ioReader = mock(ProcIoDataReader.class);
-        when(ioReader.read(PID)).thenReturn(data);
-        Clock clock = mock(Clock.class);
-
-        VmIoStatBuilder builder = new VmIoStatBuilder(clock, ioReader, writerID);
-
-        VmIoStat ioData = builder.build("vmId", PID);
-        assertNotNull(ioData);
-        assertEquals(rchar, ioData.getCharactersRead());
-        assertEquals(wchar, ioData.getCharactersWritten());
-        assertEquals(syscr, ioData.getReadSyscalls());
-        assertEquals(syscw, ioData.getWriteSyscalls());
-    }
-
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-io/agent/src/test/java/com/redhat/thermostat/vm/io/agent/internal/WindowsVmIoStatBuilderTest.java	Mon Jan 23 10:11:31 2017 -0500
@@ -0,0 +1,72 @@
+/*
+ * 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.io.agent.internal;
+
+import com.redhat.thermostat.common.Clock;
+import com.redhat.thermostat.shared.config.OS;
+import com.redhat.thermostat.storage.core.WriterID;
+import com.redhat.thermostat.vm.io.common.VmIoStat;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class WindowsVmIoStatBuilderTest {
+
+    private WriterID writerID;
+
+    @Before
+    public void setup() {
+        writerID = mock(WriterID.class);
+    }
+
+    @Test
+    public void testBuilderBuildsNullForUnknownPid() {
+        Assume.assumeTrue(OS.IS_WINDOWS);
+        Clock clock = mock(Clock.class);
+        VmIoStatBuilder builder = new WindowsVmIoStatBuilder(clock, writerID);
+        VmIoStat result = builder.build("vmId", 0);
+        assertNull(result);
+    }
+
+}
+