changeset 1100:c469675494d7

Enforce localization where appropriate via String wrapper reviewed-by: omajid review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-May/006503.html
author Jon VanAlten <jon.vanalten@redhat.com>
date Thu, 02 May 2013 10:58:20 -0600
parents 07dca767d55d
children 97e66ed2e4ae
files agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/ServiceCommand.java agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/DBStartupConfiguration.java agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/MongoProcessRunner.java agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/StalePidFileException.java agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/StorageCommand.java agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/locale/LocaleResources.java agent/cli/src/main/resources/com/redhat/thermostat/agent/cli/impl/strings.properties agent/core/pom.xml agent/core/src/main/java/com/redhat/thermostat/agent/config/AgentConfigsUtils.java agent/core/src/main/java/com/redhat/thermostat/agent/locale/LocaleResources.java agent/core/src/main/resources/com/redhat/thermostat/agent/locale/strings.properties agent/core/src/test/java/com/redhat/thermostat/agent/locale/LocaleResourcesTest.java client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/ConnectCommand.java client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/LocaleResources.java client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/ShellCommand.java client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMInfoCommand.java client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMListFormatter.java client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMStatPrinter.java client/cli/src/main/resources/com/redhat/thermostat/client/cli/strings.properties client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/ConnectCommandTest.java client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/DisconnectCommandTest.java client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/ListVMsCommandTest.java client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/VMInfoCommandTest.java client/command/src/main/java/com/redhat/thermostat/client/command/cli/PingCommand.java client/core/src/main/java/com/redhat/thermostat/client/core/controllers/InformationServiceController.java client/core/src/main/java/com/redhat/thermostat/client/core/views/HostInformationView.java client/core/src/main/java/com/redhat/thermostat/client/core/views/VmInformationView.java client/core/src/main/java/com/redhat/thermostat/client/ui/AgentInformationDisplayController.java client/core/src/main/java/com/redhat/thermostat/client/ui/HostInformationController.java client/core/src/main/java/com/redhat/thermostat/client/ui/VmInformationController.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ActionButton.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/LabelField.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/RecentTimeSeriesChartPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SearchField.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SectionHeader.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/AboutDialog.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/Main.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindow.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/AgentInformationDisplayFrame.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/ClientConfigurationPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/ClientConfigurationSwing.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/HostInformationPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/SummaryPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/VmInformationPanel.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/ActionButtonTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/HeaderPanelTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/views/HostInformationPanelTest.java common/core/src/main/java/com/redhat/thermostat/common/ApplicationInfo.java common/core/src/main/java/com/redhat/thermostat/common/Size.java common/core/src/main/java/com/redhat/thermostat/common/Version.java common/core/src/main/java/com/redhat/thermostat/common/cli/CommandException.java common/core/src/main/java/com/redhat/thermostat/common/config/Configuration.java common/core/src/main/java/com/redhat/thermostat/common/config/InvalidConfigurationException.java common/core/src/main/java/com/redhat/thermostat/common/locale/LocaleResources.java common/core/src/main/java/com/redhat/thermostat/common/locale/LocalizedString.java common/core/src/main/java/com/redhat/thermostat/common/locale/Translate.java common/core/src/main/java/com/redhat/thermostat/common/tools/StorageAuthInfoGetter.java common/core/src/main/java/com/redhat/thermostat/common/utils/LoggingUtils.java common/core/src/main/resources/com/redhat/thermostat/common/locale/strings.properties common/core/src/test/java/com/redhat/thermostat/common/ApplicationInfoTest.java common/core/src/test/java/com/redhat/thermostat/common/VersionTest.java common/core/src/test/java/com/redhat/thermostat/common/cli/CommandExceptionTest.java common/core/src/test/java/com/redhat/thermostat/common/locale/TranslateTest.java common/test/pom.xml eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/RecentTimeSeriesChartComposite.java eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostCpuView.java eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostMemoryView.java eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTVmCpuView.java eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTVmGcView.java eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/src/com/redhat/thermostat/eclipse/chart/vmclassstat/SWTVmClassStatView.java eclipse/com.redhat.thermostat.eclipse.test.ui/META-INF/MANIFEST.MF eclipse/com.redhat.thermostat.eclipse.test.ui/src/com/redhat/thermostat/eclipse/test/ui/SWTHostCpuViewTest.java eclipse/com.redhat.thermostat.eclipse.test.ui/src/com/redhat/thermostat/eclipse/test/ui/SWTHostMemoryViewTest.java eclipse/com.redhat.thermostat.eclipse.test.ui/src/com/redhat/thermostat/eclipse/test/ui/SWTVmGcViewTest.java eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/views/SWTHostOverviewView.java host-cpu/client-core/src/main/java/com/redhat/thermostat/host/cpu/client/core/HostCpuView.java host-cpu/client-core/src/main/java/com/redhat/thermostat/host/cpu/client/core/internal/HostCpuController.java host-cpu/client-core/src/test/java/com/redhat/thermostat/host/cpu/client/core/internal/HostCpuControllerTest.java host-cpu/client-swing/src/main/java/com/redhat/thermostat/host/cpu/client/swing/internal/HostCpuPanel.java host-memory/client-core/src/main/java/com/redhat/thermostat/host/memory/client/core/HostMemoryView.java host-memory/client-core/src/main/java/com/redhat/thermostat/host/memory/client/core/internal/HostMemoryController.java host-memory/client-swing/src/main/java/com/redhat/thermostat/host/memory/client/swing/internal/HostMemoryPanel.java host-overview/client-core/src/main/java/com/redhat/thermostat/host/overview/client/core/internal/HostOverviewController.java integration-tests/src/test/java/com/redhat/thermostat/itest/CliTest.java killvm/client-swing/src/main/java/com/redhat/thermostat/killvm/client/internal/KillVMAction.java killvm/client-swing/src/main/java/com/redhat/thermostat/killvm/client/internal/SwingVMKilledListener.java killvm/client-swing/src/test/java/com/redhat/thermostat/killvm/client/locale/TranslateTest.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/CommandLineArgumentParseException.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/CommandLineArgumentsParser.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/CommonOptions.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/HelpCommand.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/LocaleResources.java launcher/src/main/resources/com/redhat/thermostat/launcher/internal/strings.properties launcher/src/test/java/com/redhat/thermostat/launcher/internal/BuiltInCommandInfoTest.java launcher/src/test/java/com/redhat/thermostat/launcher/internal/LauncherImplTest.java launcher/src/test/java/com/redhat/thermostat/launcher/internal/PluginConfigurationParserTest.java numa/client-core/src/main/java/com/redhat/thermostat/numa/client/core/NumaView.java numa/client-core/src/main/java/com/redhat/thermostat/numa/client/core/internal/NumaController.java numa/client-core/src/test/java/com/redhat/thermostat/numa/client/core/internal/NumaControllerTest.java numa/client-swing/src/main/java/com/redhat/thermostat/numa/client/swing/internal/NumaPanel.java thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/collector/impl/ThreadMXBeanCollector.java thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/view/ThreadView.java thread/client-controllers/pom.xml thread/client-controllers/src/main/java/com/redhat/thermostat/thread/client/controller/impl/LocaleResources.java thread/client-controllers/src/main/java/com/redhat/thermostat/thread/client/controller/impl/ThreadInformationController.java thread/client-controllers/src/main/resources/com/redhat/thermostat/thread/client/controller/impl/strings.properties thread/client-controllers/src/test/java/com/redhat/thermostat/thread/client/controller/impl/LocaleResourcesTest.java thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadCountView.java thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadDetailsView.java thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadTableView.java thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadView.java thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/ThreadAliveDaemonTimelinePanel.java thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/ThreadMainPanel.java thread/client-swing/src/test/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadViewTest.java vm-classstat/client-core/src/main/java/com/redhat/thermostat/vm/classstat/client/core/internal/VmClassStatController.java vm-classstat/client-swing/src/main/java/com/redhat/thermostat/vm/classstat/client/swing/VmClassStatPanel.java vm-cpu/client-cli/src/main/java/com/redhat/thermostat/vm/cpu/client/cli/internal/VmCpuStatPrintDelegate.java vm-cpu/client-core/src/main/java/com/redhat/thermostat/vm/cpu/client/core/internal/VmCpuController.java vm-cpu/client-swing/src/main/java/com/redhat/thermostat/vm/cpu/client/swing/internal/VmCpuPanel.java vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/VmGcView.java vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/internal/VmGcController.java vm-gc/client-swing/src/main/java/com/redhat/thermostat/vm/gc/client/swing/internal/VmGcPanel.java vm-gc/remote-collector-client-swing/src/main/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButton.java vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapDumpDetailsView.java vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapView.java vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpController.java vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpDetailsController.java vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/ObjectRootsController.java vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpControllerTest.java vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpDetailsControllerTest.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapDetailsSwing.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapSwingView.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HistogramPanel.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectDetailsPanel.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectRootsFrame.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/stats/HeapDumperPopup.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/stats/StatsPanel.java vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapDetailsSwingTest.java vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/DumpHeapCommand.java vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/FindObjectsCommand.java vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/FindRootCommand.java vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ListHeapDumpsCommand.java vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ObjectInfoCommand.java vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/SaveHeapDumpToFileCommand.java vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ShowHeapHistogramCommand.java vm-heap-analysis/command/src/test/java/com/redhat/thermostat/vm/heap/analysis/command/internal/DumpHeapCommandTest.java vm-heap-analysis/command/src/test/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ObjectInfoCommandTest.java vm-heap-analysis/command/src/test/java/com/redhat/thermostat/vm/heap/analysis/command/internal/SaveHeapDumpToFileCommandTest.java vm-heap-analysis/command/src/test/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ShowHeapHistogramCommandTest.java vm-jmx/client-core/src/main/java/com/redhat/thermostat/vm/jmx/client/core/internal/JmxNotificationsViewController.java vm-jmx/client-core/src/main/java/com/redhat/thermostat/vm/jmx/client/core/internal/LocaleResources.java vm-jmx/client-core/src/main/resources/com/redhat/thermostat/vm/jmx/client/core/internal/strings.properties vm-jmx/client-core/src/test/java/com/redhat/thermostat/vm/jmx/client/core/internal/JmxNotificationsViewControllerTest.java vm-jmx/client-core/src/test/java/com/redhat/thermostat/vm/jmx/client/core/internal/LocaleResourcesTest.java vm-memory/client-cli/src/main/java/com/redhat/thermostat/vm/memory/client/cli/internal/VmMemoryStatPrintDelegate.java vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/MemoryStatsView.java vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/internal/MemoryStatsController.java vm-memory/client-swing/src/main/java/com/redhat/thermostat/vm/memory/client/swing/internal/MemoryStatsViewImpl.java vm-overview/client-core/src/main/java/com/redhat/thermostat/vm/overview/client/core/internal/VmOverviewController.java vm-overview/client-core/src/test/java/com/redhat/thermostat/vm/overview/client/core/internal/VmOverviewControllerTest.java vm-overview/client-swing/src/main/java/com/redhat/thermostat/vm/overview/client/swing/internal/VmOverviewPanel.java web/cmd/pom.xml web/cmd/src/main/java/com/redhat/thermostat/web/cmd/LocaleResources.java web/cmd/src/main/java/com/redhat/thermostat/web/cmd/WebServiceLauncher.java web/cmd/src/main/resources/com/redhat/thermostat/web/cmd/strings.properties web/cmd/src/test/java/com/redhat/thermostat/web/cmd/LocaleResourcesTest.java
diffstat 167 files changed, 1092 insertions(+), 464 deletions(-) [+]
line wrap: on
line diff
--- a/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/ServiceCommand.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/ServiceCommand.java	Thu May 02 10:58:20 2013 -0600
@@ -104,15 +104,15 @@
             case START:
                 String dbUrl = storage.getConfiguration().getDBConnectionString();
                 String[] agentArgs =  new String[] {"agent", "-d", dbUrl};
-                System.err.println(translator.localize(LocaleResources.STARTING_AGENT));
+                System.err.println(translator.localize(LocaleResources.STARTING_AGENT).getContents());
                 launcher.run(agentArgs, false);
                 agentBarrier.release();
                 break;
             case FAIL:
-                System.err.println(translator.localize(LocaleResources.ERROR_STARTING_DB));
+                System.err.println(translator.localize(LocaleResources.ERROR_STARTING_DB).getContents());
                 Object payload = actionEvent.getPayload();
                 if (payload instanceof StorageAlreadyRunningException) {
-                    System.err.println(translator.localize(LocaleResources.STORAGE_ALREADY_RUNNING));
+                    System.err.println(translator.localize(LocaleResources.STORAGE_ALREADY_RUNNING).getContents());
                 }
                 break;
             }
--- a/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/DBStartupConfiguration.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/DBStartupConfiguration.java	Thu May 02 10:58:20 2013 -0600
@@ -41,11 +41,15 @@
 import java.io.IOException;
 import java.util.Properties;
 
+import com.redhat.thermostat.agent.cli.impl.locale.LocaleResources;
 import com.redhat.thermostat.common.config.InvalidConfigurationException;
+import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.storage.config.StartupConfiguration;
 
 public class DBStartupConfiguration implements StartupConfiguration {
-    
+
+    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
+
     private File dbPath;
     private File logFile;
     private File pidFile;
@@ -153,14 +157,14 @@
             int localPort = Integer.parseInt(port);
             setPort(localPort);
         } else {
-            throw new InvalidConfigurationException(DBConfig.PORT + " property missing");
+            throw new InvalidConfigurationException(t.localize(LocaleResources.MISSING_PROPERTY, DBConfig.PORT.toString()));
         }
         
         if (properties.containsKey(DBConfig.BIND.name())) {
             String ip = (String) properties.get(DBConfig.BIND.name());
             setBindIP(ip);
         } else {
-            throw new InvalidConfigurationException(DBConfig.BIND + " property missing");
+            throw new InvalidConfigurationException(t.localize(LocaleResources.MISSING_PROPERTY, DBConfig.BIND.toString()));
         }
         
         // optional config
--- a/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/MongoProcessRunner.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/MongoProcessRunner.java	Thu May 02 10:58:20 2013 -0600
@@ -51,6 +51,7 @@
 
 import com.redhat.thermostat.agent.cli.impl.locale.LocaleResources;
 import com.redhat.thermostat.common.config.InvalidConfigurationException;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.common.tools.ApplicationException;
 import com.redhat.thermostat.common.utils.LoggedExternalProcess;
@@ -122,11 +123,11 @@
             }
         } else {
             
-            String message = translator.localize(LocaleResources.CANNOT_SHUTDOWN_SERVER,
+            LocalizedString message = translator.localize(LocaleResources.CANNOT_SHUTDOWN_SERVER,
                     configuration.getDBPath().toString(),
                     String.valueOf(status));
             display(message);
-            throw new StorageStopException(configuration.getDBPath(), status, message);
+            throw new StorageStopException(configuration.getDBPath(), status, message.getContents());
         }
     }
     
@@ -145,12 +146,12 @@
 
         String pid = getPid();
         if (pid != null) {
-            String message = null;
+            LocalizedString message = null;
             if (!checkExistingProcess()) {
                 message = translator.localize(LocaleResources.STALE_PID_FILE_NO_MATCHING_PROCESS, configuration.getPidFile().toString(), MONGO_PROCESS);
                 // Mongo didn't remove its PID file? Work around the issue. Log
                 // the event, remove the stale pid file and continue.
-                logger.log(Level.WARNING, message);
+                logger.log(Level.WARNING, message.getContents());
                 try {
                     Files.delete(configuration.getPidFile().toPath());
                 } catch (IOException benign) {
@@ -159,7 +160,7 @@
             } else {
                 message = translator.localize(LocaleResources.STORAGE_ALREADY_RUNNING_WITH_PID, String.valueOf(pid));
                 display(message);
-                throw new StorageAlreadyRunningException(Integer.valueOf(pid), message);
+                throw new StorageAlreadyRunningException(Integer.valueOf(pid), message.getContents());
             }
         }
         
@@ -174,7 +175,7 @@
         try {
             status = process.runAndReturnResult();
         } catch (ApplicationException ae) {
-            String message = translator.localize(LocaleResources.CANNOT_EXECUTE_PROCESS, MONGO_PROCESS);
+            LocalizedString message = translator.localize(LocaleResources.CANNOT_EXECUTE_PROCESS, MONGO_PROCESS);
             display(message);
             throw ae;
         }
@@ -193,11 +194,11 @@
             
         } else {
             
-            String message = translator.localize(LocaleResources.CANNOT_START_SERVER,
+            LocalizedString message = translator.localize(LocaleResources.CANNOT_START_SERVER,
                              configuration.getDBPath().toString(),
                              String.valueOf(status));
             display(message);
-            throw new StorageStartException(configuration.getDBPath(), status, message);
+            throw new StorageStartException(configuration.getDBPath(), status, message.getContents());
         }
     }
     
@@ -224,9 +225,9 @@
         if (configuration.isSslEnabled()) {
             // check for configuration which has a chance of working :)
             if (configuration.getSslPemFile() == null) {
-                throw new InvalidConfigurationException("No SSL PEM file specified!");
+                throw new InvalidConfigurationException(translator.localize(LocaleResources.MISSING_PEM));
             } else if (configuration.getSslKeyPassphrase() == null) {
-                throw new InvalidConfigurationException("No SSL key passphrase set!");
+                throw new InvalidConfigurationException(translator.localize(LocaleResources.MISSING_PASSPHRASE));
             }
             commands.add("--sslOnNormalPorts");
             commands.add("--sslPEMKeyFile");
@@ -244,7 +245,7 @@
             process = new ProcessBuilder(Arrays.asList("mongod", "--version"))
                     .start();
         } catch (IOException e) {
-            String message = translator.localize(
+            LocalizedString message = translator.localize(
                     LocaleResources.CANNOT_EXECUTE_PROCESS, MONGO_PROCESS);
             display(message);
             throw e;
@@ -258,9 +259,9 @@
         return versionString;
     }
 
-    private void display(String message) {
+    private void display(LocalizedString message) {
         if (!isQuiet) {
-            System.out.println(message);
+            System.out.println(message.getContents());
         }
     }
 }
--- a/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/StalePidFileException.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/StalePidFileException.java	Thu May 02 10:58:20 2013 -0600
@@ -49,7 +49,7 @@
     private final File pidFile;
 
     public StalePidFileException(File pidFile) {
-        super(translator.localize(LocaleResources.STALE_PID_FILE, pidFile.toString()));
+        super(translator.localize(LocaleResources.STALE_PID_FILE, pidFile.toString()).getContents());
         this.pidFile = pidFile;
     }
 
--- a/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/StorageCommand.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/StorageCommand.java	Thu May 02 10:58:20 2013 -0600
@@ -39,6 +39,7 @@
 import java.io.File;
 import java.io.IOException;
 
+import com.redhat.thermostat.agent.cli.impl.locale.LocaleResources;
 import com.redhat.thermostat.common.ExitStatus;
 import com.redhat.thermostat.common.cli.AbstractStateNotifyingCommand;
 import com.redhat.thermostat.common.cli.Arguments;
@@ -46,11 +47,14 @@
 import com.redhat.thermostat.common.cli.CommandException;
 import com.redhat.thermostat.common.config.Configuration;
 import com.redhat.thermostat.common.config.InvalidConfigurationException;
+import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.common.tools.ApplicationException;
 import com.redhat.thermostat.common.tools.ApplicationState;
 
 public class StorageCommand extends AbstractStateNotifyingCommand {
 
+    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
+
     private DBStartupConfiguration configuration;
     private DBOptionParser parser;
     private final ExitStatus exitStatus;
@@ -69,8 +73,7 @@
         File pidFile = thermostatConfiguration.getStoragePidFile();
         File propertyFile = thermostatConfiguration.getStorageConfigurationFile();
         if (!propertyFile.exists()) {
-            throw new InvalidConfigurationException("can't access database configuration file " +
-                                                    propertyFile);
+            throw new InvalidConfigurationException(t.localize(LocaleResources.MISSING_DB_CONFIG, propertyFile.toString()));
         }
         // read everything that is in the configs
         this.configuration = new DBStartupConfiguration(propertyFile, dbPath, logFile, pidFile);
@@ -152,7 +155,7 @@
             !configuration.getLogFile().getParentFile().exists() || 
             !configuration.getPidFile().getParentFile().exists())
         {
-            throw new InvalidConfigurationException("database directories do not exist...");
+            throw new InvalidConfigurationException(t.localize(LocaleResources.MISSING_DB_DIR));
         }
     }
 
--- a/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/locale/LocaleResources.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/locale/LocaleResources.java	Thu May 02 10:58:20 2013 -0600
@@ -57,7 +57,13 @@
     CANNOT_EXECUTE_PROCESS,
     SERVER_LISTENING_ON,
     PID_IS,
-    LAUNCHER_UNAVAILABLE;
+    LAUNCHER_UNAVAILABLE,
+    MISSING_PROPERTY,
+    MISSING_PEM,
+    MISSING_PASSPHRASE,
+    MISSING_DB_CONFIG,
+    MISSING_DB_DIR,
+    ;
 
     static final String RESOURCE_BUNDLE = "com.redhat.thermostat.agent.cli.impl.strings";
 
--- a/agent/cli/src/main/resources/com/redhat/thermostat/agent/cli/impl/strings.properties	Thu Apr 25 17:27:42 2013 -0600
+++ b/agent/cli/src/main/resources/com/redhat/thermostat/agent/cli/impl/strings.properties	Thu May 02 10:58:20 2013 -0600
@@ -16,3 +16,8 @@
 SERVER_LISTENING_ON = server listening on ip: {0}
 PID_IS = pid: {0}
 LAUNCHER_UNAVAILABLE = Launcher is not available
+MISSING_PROPERTY = {0} property missing
+MISSING_PEM = No SSL PEM file specified!
+MISSING_PASSPHRASE = No SSL key passphrase set!
+MISSING_DB_CONFIG = can't access database configuration file {0}
+MISSING_DB_DIR = database directories do not exist...
--- a/agent/core/pom.xml	Thu Apr 25 17:27:42 2013 -0600
+++ b/agent/core/pom.xml	Thu May 02 10:58:20 2013 -0600
@@ -122,6 +122,7 @@
             </Export-Package>
             <Private-Package>
               com.redhat.thermostat.agent.internal,
+              com.redhat.thermostat.agent.locale,
               com.redhat.thermostat.backend.internal,
               com.redhat.thermostat.utils.management.internal,
             </Private-Package>
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/config/AgentConfigsUtils.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/agent/core/src/main/java/com/redhat/thermostat/agent/config/AgentConfigsUtils.java	Thu May 02 10:58:20 2013 -0600
@@ -45,9 +45,13 @@
 
 import com.redhat.thermostat.common.config.Configuration;
 import com.redhat.thermostat.common.config.InvalidConfigurationException;
+import com.redhat.thermostat.agent.locale.LocaleResources;
+import com.redhat.thermostat.common.locale.Translate;
 
 public class AgentConfigsUtils {
 
+    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
+
     private static char[] pw = {'p', 'a', 's', 's', 'w', 'o', 'r', 'd'};
     private static char[] user = {'u', 's', 'e', 'r', 'n', 'a', 'm', 'e'};
     private static String newLine = System.lineSeparator();
@@ -103,22 +107,25 @@
         config.setPassword("");
         if (authFile.canRead() && authFile.isFile()) {
             long length = authFile.length();
-            if (length > Integer.MAX_VALUE || length < 0L) {
-                throw new InvalidConfigurationException("agent.auth file not valid");
-            }
-            int len = (int) length; // A reasonable file will be within int range.
-            // file size in bytes >= # of chars so this size should be sufficient.
-            char[] authData = new char[len];
-            // This is probably the most sensitive time for password-in-heap exposure.
-            // The reader here may contain buffers containing the password.  It will,
-            // of course, be garbage collected in due time.
+            char[] authData = null;
             try (FileReader reader = new FileReader(authFile)) {
+                if (length > Integer.MAX_VALUE || length < 0L) {
+                    throw new InvalidConfigurationException(t.localize(LocaleResources.FILE_NOT_VALID, authFile.getCanonicalPath()));
+                }
+                int len = (int) length; // A reasonable file will be within int range.
+                // file size in bytes >= # of chars so this size should be sufficient.
+                authData = new char[len];
+                // This is probably the most sensitive time for password-in-heap exposure.
+                // The reader here may contain buffers containing the password.  It will,
+                // of course, be garbage collected in due time.
                 int chars = reader.read(authData, 0, len);
                 parseAuthConfigFromData(authData, chars, config);
             } catch (IOException e) {
                 throw new InvalidConfigurationException(e);
             } finally {
-                Arrays.fill(authData, '\0');
+                if (authData != null) {
+                    Arrays.fill(authData, '\0');
+                }
             }
         }
     }
@@ -153,7 +160,7 @@
                 value = null;
                 continue;
             }
-            throw new InvalidConfigurationException("Unrecognized content in agent auth file.");
+            throw new InvalidConfigurationException(t.localize(LocaleResources.BAD_AGENT_AUTH_CONTENTS));
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/core/src/main/java/com/redhat/thermostat/agent/locale/LocaleResources.java	Thu May 02 10:58:20 2013 -0600
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2012, 2013 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.locale;
+
+import com.redhat.thermostat.common.locale.Translate;
+
+public enum LocaleResources {
+
+    FILE_NOT_VALID,
+    BAD_AGENT_AUTH_CONTENTS,
+    ;
+    static final String RESOURCE_BUNDLE = "com.redhat.thermostat.agent.locale.strings";
+
+    public static Translate<LocaleResources> createLocalizer() {
+        return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/core/src/main/resources/com/redhat/thermostat/agent/locale/strings.properties	Thu May 02 10:58:20 2013 -0600
@@ -0,0 +1,2 @@
+FILE_NOT_VALID = File not valid: {1}
+BAD_AGENT_AUTH_CONTENTS = Unrecognized content in agent auth file.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/core/src/test/java/com/redhat/thermostat/agent/locale/LocaleResourcesTest.java	Thu May 02 10:58:20 2013 -0600
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2012, 2013 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.locale;
+
+import com.redhat.thermostat.testutils.AbstractLocaleResourcesTest;
+
+public class LocaleResourcesTest  extends AbstractLocaleResourcesTest<LocaleResources> {
+
+    @Override
+    protected Class<LocaleResources> getEnumClass() {
+        return LocaleResources.class;
+    }
+
+    @Override
+    protected String getResourceBundle() {
+        return LocaleResources.RESOURCE_BUNDLE;
+    }
+
+}
--- a/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/ConnectCommand.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/ConnectCommand.java	Thu May 02 10:58:20 2013 -0600
@@ -129,7 +129,7 @@
             throw new CommandException(translator.localize(LocaleResources.COMMAND_CONNECT_INVALID_STORAGE, dbUrl));
         } catch (ConnectionException ex) {
             String error = ex.getMessage();
-            String message = ( error == null ? "" : " " + translator.localize(LocaleResources.COMMAND_CONNECT_ERROR, error) );
+            String message = ( error == null ? "" : " " + translator.localize(LocaleResources.COMMAND_CONNECT_ERROR, error).getContents() );
             throw new CommandException(translator.localize(LocaleResources.COMMAND_CONNECT_FAILED_TO_CONNECT, dbUrl + message), ex);
         }
     }
--- a/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/LocaleResources.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/LocaleResources.java	Thu May 02 10:58:20 2013 -0600
@@ -41,6 +41,7 @@
 public enum LocaleResources {
 
     MISSING_INFO,
+    MISSING_LAUNCHER,
 
     HOST_SERVICE_UNAVAILABLE,
     VM_SERVICE_UNAVAILABLE,
--- a/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/ShellCommand.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/ShellCommand.java	Thu May 02 10:58:20 2013 -0600
@@ -60,11 +60,13 @@
 import com.redhat.thermostat.common.cli.Console;
 import com.redhat.thermostat.common.config.Configuration;
 import com.redhat.thermostat.common.config.InvalidConfigurationException;
+import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 
 public class ShellCommand extends AbstractCommand {
 
     private static final Logger logger = LoggingUtils.getLogger(ShellCommand.class);
+    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
 
     private static final String[] exitKeywords = { "exit", "quit", "q" };
 
@@ -170,7 +172,7 @@
             Launcher launcher = (Launcher) bundleContext.getService(launcherRef);
             launcher.run(parsed, true);
         } else {
-            throw new CommandException("Severe: Could not locate launcher");
+            throw new CommandException(t.localize(LocaleResources.MISSING_LAUNCHER));
         }
     }
 
--- a/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMInfoCommand.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMInfoCommand.java	Thu May 02 10:58:20 2013 -0600
@@ -60,7 +60,7 @@
 
     private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
 
-    private static final String STILL_ALIVE = translator.localize(LocaleResources.VM_STOP_TIME_RUNNING);
+    private static final String STILL_ALIVE = translator.localize(LocaleResources.VM_STOP_TIME_RUNNING).getContents();
 
     private final BundleContext context;
 
@@ -110,18 +110,18 @@
         VmInfo vmInfo = vmsDAO.getVmInfo(vm);
 
         TableRenderer table = new TableRenderer(2);
-        table.printLine(translator.localize(LocaleResources.VM_INFO_PROCESS_ID), String.valueOf(vmInfo.getVmPid()));
-        table.printLine(translator.localize(LocaleResources.VM_INFO_START_TIME), new Date(vmInfo.getStartTimeStamp()).toString());
+        table.printLine(translator.localize(LocaleResources.VM_INFO_PROCESS_ID).getContents(), String.valueOf(vmInfo.getVmPid()));
+        table.printLine(translator.localize(LocaleResources.VM_INFO_START_TIME).getContents(), new Date(vmInfo.getStartTimeStamp()).toString());
         if (vmInfo.isAlive()) {
-            table.printLine(translator.localize(LocaleResources.VM_INFO_STOP_TIME), STILL_ALIVE);
+            table.printLine(translator.localize(LocaleResources.VM_INFO_STOP_TIME).getContents(), STILL_ALIVE);
         } else {
-            table.printLine(translator.localize(LocaleResources.VM_INFO_STOP_TIME), new Date(vmInfo.getStopTimeStamp()).toString());
+            table.printLine(translator.localize(LocaleResources.VM_INFO_STOP_TIME).getContents(), new Date(vmInfo.getStopTimeStamp()).toString());
         }
-        table.printLine(translator.localize(LocaleResources.VM_INFO_MAIN_CLASS), vmInfo.getMainClass());
-        table.printLine(translator.localize(LocaleResources.VM_INFO_COMMAND_LINE), vmInfo.getJavaCommandLine());
-        table.printLine(translator.localize(LocaleResources.VM_INFO_JAVA_VERSION), vmInfo.getJavaVersion());
-        table.printLine(translator.localize(LocaleResources.VM_INFO_VIRTUAL_MACHINE), vmInfo.getVmName());
-        table.printLine(translator.localize(LocaleResources.VM_INFO_VM_ARGUMENTS), vmInfo.getVmArguments());
+        table.printLine(translator.localize(LocaleResources.VM_INFO_MAIN_CLASS).getContents(), vmInfo.getMainClass());
+        table.printLine(translator.localize(LocaleResources.VM_INFO_COMMAND_LINE).getContents(), vmInfo.getJavaCommandLine());
+        table.printLine(translator.localize(LocaleResources.VM_INFO_JAVA_VERSION).getContents(), vmInfo.getJavaVersion());
+        table.printLine(translator.localize(LocaleResources.VM_INFO_VIRTUAL_MACHINE).getContents(), vmInfo.getVmName());
+        table.printLine(translator.localize(LocaleResources.VM_INFO_VM_ARGUMENTS).getContents(), vmInfo.getVmArguments());
 
         PrintStream out = ctx.getConsole().getOutput();
         table.render(out);
--- a/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMListFormatter.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMListFormatter.java	Thu May 02 10:58:20 2013 -0600
@@ -47,14 +47,14 @@
 
     private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
 
-    private static final String HOST_ID = translator.localize(LocaleResources.COLUMN_HEADER_HOST_ID);
-    private static final String HOST = translator.localize(LocaleResources.COLUMN_HEADER_HOST);
-    private static final String VM_ID = translator.localize(LocaleResources.COLUMN_HEADER_VM_ID);
-    private static final String VM_NAME = translator.localize(LocaleResources.COLUMN_HEADER_VM_NAME);
-    private static final String VM_STATUS = translator.localize(LocaleResources.COLUMN_HEADER_VM_STATUS);
+    private static final String HOST_ID = translator.localize(LocaleResources.COLUMN_HEADER_HOST_ID).getContents();
+    private static final String HOST = translator.localize(LocaleResources.COLUMN_HEADER_HOST).getContents();
+    private static final String VM_ID = translator.localize(LocaleResources.COLUMN_HEADER_VM_ID).getContents();
+    private static final String VM_NAME = translator.localize(LocaleResources.COLUMN_HEADER_VM_NAME).getContents();
+    private static final String VM_STATUS = translator.localize(LocaleResources.COLUMN_HEADER_VM_STATUS).getContents();
 
-    private static final String STATUS_ALIVE = translator.localize(LocaleResources.VM_STATUS_ALIVE);
-    private static final String STATUS_DEAD = translator.localize(LocaleResources.VM_STATUS_DEAD);
+    private static final String STATUS_ALIVE = translator.localize(LocaleResources.VM_STATUS_ALIVE).getContents();
+    private static final String STATUS_DEAD = translator.localize(LocaleResources.VM_STATUS_DEAD).getContents();
 
     private TableRenderer tableRenderer;
 
--- a/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMStatPrinter.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMStatPrinter.java	Thu May 02 10:58:20 2013 -0600
@@ -61,7 +61,7 @@
 
     private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
 
-    private static final String TIME = translator.localize(LocaleResources.COLUMN_HEADER_TIME);
+    private static final String TIME = translator.localize(LocaleResources.COLUMN_HEADER_TIME).getContents();
 
     private VmRef vm;
     private List<VMStatPrintDelegate> delegates;
--- a/client/cli/src/main/resources/com/redhat/thermostat/client/cli/strings.properties	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/cli/src/main/resources/com/redhat/thermostat/client/cli/strings.properties	Thu May 02 10:58:20 2013 -0600
@@ -1,4 +1,5 @@
 MISSING_INFO = Missing Information
+MISSING_LAUNCHER = Fatal Error: Could not locate launcher
 
 HOST_SERVICE_UNAVAILABLE = Unable to get host information (HostInfoDAO is unavailable)
 VM_SERVICE_UNAVAILABLE = Unable to get vm information (VmInfoDAO is unavailable)
--- a/client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/ConnectCommandTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/ConnectCommandTest.java	Thu May 02 10:58:20 2013 -0600
@@ -109,7 +109,7 @@
         try {
             cmd.run(cmdCtxFactory.createContext(args));
         } catch (CommandException e) {
-            assertEquals(translator.localize(LocaleResources.COMMAND_CONNECT_ALREADY_CONNECTED, dbUrl), e.getMessage());
+            assertEquals(translator.localize(LocaleResources.COMMAND_CONNECT_ALREADY_CONNECTED, dbUrl).getContents(), e.getMessage());
         }
     }
     
@@ -144,7 +144,7 @@
             cmd.run(ctx);
             fail();
         } catch (CommandException e) {
-            assertEquals(translator.localize(LocaleResources.COMMAND_CONNECT_NO_KEYRING), e.getMessage());
+            assertEquals(translator.localize(LocaleResources.COMMAND_CONNECT_NO_KEYRING).getContents(), e.getMessage());
         }
         
         verify(dbService, never()).connect();
--- a/client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/DisconnectCommandTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/DisconnectCommandTest.java	Thu May 02 10:58:20 2013 -0600
@@ -83,7 +83,7 @@
             cmd.run(cmdCtxFactory.createContext(new SimpleArguments()));
             fail("cmd.run() should have thrown exception.");
         } catch (CommandException e) {
-            assertEquals(translator.localize(LocaleResources.COMMAND_DISCONNECT_NOT_CONNECTED), e.getMessage());
+            assertEquals(translator.localize(LocaleResources.COMMAND_DISCONNECT_NOT_CONNECTED).getContents(), e.getMessage());
         }
     }
     
--- a/client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/ListVMsCommandTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/ListVMsCommandTest.java	Thu May 02 10:58:20 2013 -0600
@@ -162,7 +162,7 @@
             cmd.run(ctx);
             fail();
         } catch (CommandException e) {
-            assertEquals(translator.localize(LocaleResources.HOST_SERVICE_UNAVAILABLE), e.getMessage());
+            assertEquals(translator.localize(LocaleResources.HOST_SERVICE_UNAVAILABLE).getContents(), e.getMessage());
         }
     }
     
@@ -178,7 +178,7 @@
             cmd.run(ctx);
             fail();
         } catch (CommandException e) {
-            assertEquals(translator.localize(LocaleResources.VM_SERVICE_UNAVAILABLE), e.getMessage());
+            assertEquals(translator.localize(LocaleResources.VM_SERVICE_UNAVAILABLE).getContents(), e.getMessage());
         }
     }
 
--- a/client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/VMInfoCommandTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/VMInfoCommandTest.java	Thu May 02 10:58:20 2013 -0600
@@ -143,7 +143,7 @@
             cmd.run(cmdCtxFactory.createContext(args));
             fail();
         } catch (CommandException e) {
-            assertEquals(translator.localize(LocaleResources.VM_SERVICE_UNAVAILABLE), e.getMessage());
+            assertEquals(translator.localize(LocaleResources.VM_SERVICE_UNAVAILABLE).getContents(), e.getMessage());
         }
     }
 
--- a/client/command/src/main/java/com/redhat/thermostat/client/command/cli/PingCommand.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/command/src/main/java/com/redhat/thermostat/client/command/cli/PingCommand.java	Thu May 02 10:58:20 2013 -0600
@@ -55,6 +55,7 @@
 import com.redhat.thermostat.common.command.Request.RequestType;
 import com.redhat.thermostat.common.command.RequestResponseListener;
 import com.redhat.thermostat.common.command.Response;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.storage.core.HostRef;
 import com.redhat.thermostat.storage.dao.AgentInfoDAO;
@@ -78,17 +79,17 @@
         public void fireComplete(Request request, Response response) {
             switch (response.getType()) {
             case ERROR:
-                out.println(translator.localize(LocaleResources.COMMAND_PING_RESPONSE_ERROR, request.getTarget().toString()));
+                out.println(translator.localize(LocaleResources.COMMAND_PING_RESPONSE_ERROR, request.getTarget().toString()).getContents());
                 break;
             case OK:
             case NOOP:
-                out.println(translator.localize(LocaleResources.COMMAND_PING_RESPONSE_OK, request.getTarget().toString()));
+                out.println(translator.localize(LocaleResources.COMMAND_PING_RESPONSE_OK, request.getTarget().toString()).getContents());
                 break;
             case NOK:
-                out.println(translator.localize(LocaleResources.COMMAND_PING_RESPONSE_REFUSED));
+                out.println(translator.localize(LocaleResources.COMMAND_PING_RESPONSE_REFUSED).getContents());
                 break;
             default:
-                out.println(translator.localize(LocaleResources.COMMAND_PING_RESPONSE_UNKNOWN));
+                out.println(translator.localize(LocaleResources.COMMAND_PING_RESPONSE_UNKNOWN).getContents());
                 break;
             }
             responseBarrier.release();
@@ -147,7 +148,7 @@
             throw new CommandException(translator.localize(LocaleResources.COMMAND_PING_NO_REQUEST_QUEUE));
         }
         RequestQueue queue = (RequestQueue) context.getService(queueRef);
-        out.println(translator.localize(LocaleResources.COMMAND_PING_QUEUING_REQUEST, target.toString()));
+        out.println(translator.localize(LocaleResources.COMMAND_PING_QUEUING_REQUEST, target.toString()).getContents());
         queue.putRequest(ping);
         context.ungetService(queueRef);
         try {
@@ -176,8 +177,8 @@
         return targetHostRef;
     }
 
-    private void printCustomMessageWithUsage(PrintStream out, String message) {
-        out.println(message);
+    private void printCustomMessageWithUsage(PrintStream out, LocalizedString message) {
+        out.println(message.getContents());
         // FIXME add usage back out.println(getUsage());
         return;
     }
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/controllers/InformationServiceController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/core/src/main/java/com/redhat/thermostat/client/core/controllers/InformationServiceController.java	Thu May 02 10:58:20 2013 -0600
@@ -37,6 +37,7 @@
 package com.redhat.thermostat.client.core.controllers;
 
 import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.storage.core.Ref;
 
 /**
@@ -45,6 +46,6 @@
 public interface InformationServiceController<T extends Ref> {
 
     UIComponent getView();
-    String getLocalizedName();
+    LocalizedString getLocalizedName();
 }
 
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/views/HostInformationView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/core/src/main/java/com/redhat/thermostat/client/core/views/HostInformationView.java	Thu May 02 10:58:20 2013 -0600
@@ -36,6 +36,8 @@
 
 package com.redhat.thermostat.client.core.views;
 
+import com.redhat.thermostat.common.locale.LocalizedString;
+
 /**
  * A {@link View} that shows host information. It does not display
  * this information directly. It relies on child views.
@@ -44,9 +46,9 @@
  */
 public abstract class HostInformationView extends BasicView implements UIComponent {
 
-    public abstract void addChildView(String title, UIComponent view);
+    public abstract void addChildView(LocalizedString title, UIComponent view);
 
-    public abstract void removeChildView(String title);
+    public abstract void removeChildView(LocalizedString title);
 
 }
 
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/views/VmInformationView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/core/src/main/java/com/redhat/thermostat/client/core/views/VmInformationView.java	Thu May 02 10:58:20 2013 -0600
@@ -36,13 +36,15 @@
 
 package com.redhat.thermostat.client.core.views;
 
+import com.redhat.thermostat.common.locale.LocalizedString;
+
 
 public abstract class VmInformationView extends BasicView implements UIComponent {
 
     /**
      * @param view the view.
      */
-    public abstract void addChildView(String title, UIComponent view);
+    public abstract void addChildView(LocalizedString title, UIComponent view);
 
     public abstract int getNumChildren();
     public abstract boolean selectChildID(int id);
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/AgentInformationDisplayController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/AgentInformationDisplayController.java	Thu May 02 10:58:20 2013 -0600
@@ -47,6 +47,7 @@
 import com.redhat.thermostat.client.locale.LocaleResources;
 import com.redhat.thermostat.common.ActionEvent;
 import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.storage.model.AgentInformation;
 import com.redhat.thermostat.storage.model.BackendInformation;
@@ -134,16 +135,16 @@
         if (stopTime >= startTime) {
             view.setSelectedAgentStopTime(dateTimeFormat.format(new Date(stopTime)));
         } else {
-            view.setSelectedAgentStopTime(translator.localize(LocaleResources.AGENT_INFO_AGENT_RUNNING));
+            view.setSelectedAgentStopTime(translator.localize(LocaleResources.AGENT_INFO_AGENT_RUNNING).getContents());
         }
 
         // Linked to enforce order
         Map<String, String> map = new LinkedHashMap<>();
         for (BackendInformation backendInfo : model.getBackends(agentId)) {
-            String status = backendInfo.isActive() ?
+            LocalizedString status = backendInfo.isActive() ?
                     translator.localize(LocaleResources.AGENT_INFO_BACKEND_STATUS_ACTIVE)
                     : translator.localize(LocaleResources.AGENT_INFO_BACKEND_STATUS_INACTIVE);
-            map.put(backendInfo.getName(), status);
+            map.put(backendInfo.getName(), status.getContents());
         }
         view.setSelectedAgentBackendStatus(map);
     }
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/HostInformationController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/HostInformationController.java	Thu May 02 10:58:20 2013 -0600
@@ -45,6 +45,7 @@
 import com.redhat.thermostat.client.core.views.HostInformationView;
 import com.redhat.thermostat.client.core.views.HostInformationViewProvider;
 import com.redhat.thermostat.common.OrderedComparator;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.storage.core.HostRef;
 
 public class HostInformationController {
@@ -59,7 +60,7 @@
         for (InformationService<HostRef> hostInfoService : hostInfoServices) {
             if (hostInfoService.getFilter().matches(ref)) {
                 InformationServiceController<HostRef> ctrl = hostInfoService.getInformationServiceController(ref);
-                String name = ctrl.getLocalizedName();
+                LocalizedString name = ctrl.getLocalizedName();
                 view.addChildView(name, ctrl.getView());
             }
         }
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/VmInformationController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/VmInformationController.java	Thu May 02 10:58:20 2013 -0600
@@ -45,6 +45,7 @@
 import com.redhat.thermostat.client.core.views.VmInformationView;
 import com.redhat.thermostat.client.core.views.VmInformationViewProvider;
 import com.redhat.thermostat.common.OrderedComparator;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.storage.core.VmRef;
 
 public class VmInformationController {
@@ -59,7 +60,7 @@
         for (InformationService<VmRef> vmInfoService : vmInfoServices) {
             if (vmInfoService.getFilter().matches(vmRef)) {
                 InformationServiceController<VmRef> ctrl = vmInfoService.getInformationServiceController(vmRef);
-                String name = ctrl.getLocalizedName();
+                LocalizedString name = ctrl.getLocalizedName();
                 view.addChildView(name, ctrl.getView());
             }
         }
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ActionButton.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ActionButton.java	Thu May 02 10:58:20 2013 -0600
@@ -36,16 +36,11 @@
 
 package com.redhat.thermostat.client.swing.components;
 
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Graphics;
-import java.lang.reflect.InvocationTargetException;
-
 import javax.swing.AbstractButton;
 import javax.swing.Icon;
 import javax.swing.JButton;
-import javax.swing.JFrame;
-import javax.swing.SwingUtilities;
+
+import com.redhat.thermostat.common.locale.LocalizedString;
 
 /**
  * A swing implementation of {@link ToolbarButton}.
@@ -57,14 +52,14 @@
     private boolean showText;
     
     public ActionButton(final Icon icon) {
-        this(icon, "");
+        this(icon, null);
     }
     
-    public ActionButton(final Icon icon, String text) {
+    public ActionButton(final Icon icon, LocalizedString text) {
         super(icon);
                 
         showText = true;
-        setText(text);
+        setText(text == null ? "" : text.getContents());
         
         setUI(new ActionButtonUI());
         setOpaque(false);
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/LabelField.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/LabelField.java	Thu May 02 10:58:20 2013 -0600
@@ -39,14 +39,16 @@
 import javax.swing.JLabel;
 import javax.swing.SwingConstants;
 
+import com.redhat.thermostat.common.locale.LocalizedString;
+
 /**
  * A {@link JLabel} appropriate for labelling other components.
  */
 @SuppressWarnings("serial")
 public class LabelField extends JLabel {
 
-    public LabelField(String text) {
-        super(text);
+    public LabelField(LocalizedString text) {
+        super(text.getContents());
         setHorizontalAlignment(SwingConstants.TRAILING);
     }
 }
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/RecentTimeSeriesChartPanel.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/RecentTimeSeriesChartPanel.java	Thu May 02 10:58:20 2013 -0600
@@ -133,7 +133,7 @@
         durationSelector.setText(String.valueOf(defaultValue));
         unitSelector.setSelectedItem(defaultUnit);
 
-        container.add(new JLabel(translator.localize(LocaleResources.CHART_DURATION_SELECTOR_LABEL)));
+        container.add(new JLabel(translator.localize(LocaleResources.CHART_DURATION_SELECTOR_LABEL).getContents()));
         container.add(durationSelector);
         container.add(unitSelector);
 
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SearchField.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SearchField.java	Thu May 02 10:58:20 2013 -0600
@@ -42,8 +42,6 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.FocusEvent;
 import java.awt.event.FocusListener;
-import java.lang.reflect.InvocationTargetException;
-import java.util.concurrent.Callable;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -51,14 +49,12 @@
 import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JTextField;
-import javax.swing.SwingUtilities;
 import javax.swing.event.DocumentEvent;
 import javax.swing.event.DocumentListener;
 import javax.swing.text.BadLocationException;
 import javax.swing.text.Document;
 
 import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.client.swing.EdtHelper;
 import com.redhat.thermostat.client.swing.IconResource;
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.common.ActionNotifier;
@@ -86,7 +82,7 @@
     private final JTextField searchField = new JTextField();
 
     private final AtomicReference<String> searchText = new AtomicReference<String>("");
-    private final AtomicReference<String> label = new AtomicReference<>(translator.localize(LocaleResources.SEARCH_HINT));
+    private final AtomicReference<String> label = new AtomicReference<>(translator.localize(LocaleResources.SEARCH_HINT).getContents());
     private final AtomicBoolean labelDisplayed = new AtomicBoolean(true);
 
     public SearchField() {
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SectionHeader.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SectionHeader.java	Thu May 02 10:58:20 2013 -0600
@@ -39,6 +39,8 @@
 import javax.swing.JLabel;
 import javax.swing.SwingConstants;
 
+import com.redhat.thermostat.common.locale.LocalizedString;
+
 /**
  * A {@link JLabel} that is appropriate to use as a label for grouping
  * the following information together.
@@ -46,8 +48,8 @@
 @SuppressWarnings("serial")
 public class SectionHeader extends JLabel {
 
-    public SectionHeader(String text) {
-        super("<html><b>" + text + " </b><html>");
+    public SectionHeader(LocalizedString text) {
+        super("<html><b>" + text.getContents() + " </b><html>");
         setHorizontalAlignment(SwingConstants.LEADING);
     }
 }
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/AboutDialog.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/AboutDialog.java	Thu May 02 10:58:20 2013 -0600
@@ -59,7 +59,6 @@
 import javax.swing.border.TitledBorder;
 
 import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.client.swing.IconResource;
 import com.redhat.thermostat.client.swing.UIResources;
 import com.redhat.thermostat.common.ApplicationInfo;
 import com.redhat.thermostat.common.locale.Translate;
@@ -108,7 +107,7 @@
         JPanel panel = new JPanel();
         panel.setBorder(new TitledBorder(""));
         
-        JButton closeButton = new JButton(translator.localize(LocaleResources.BUTTON_CLOSE));
+        JButton closeButton = new JButton(translator.localize(LocaleResources.BUTTON_CLOSE).getContents());
         closeButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 AboutDialog.this.setVisible(false);
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/Main.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/Main.java	Thu May 02 10:58:20 2013 -0600
@@ -209,14 +209,14 @@
         @Override
         public void run() {
             Object[] options = {
-                    translator.localize(LocaleResources.CONNECTION_WIZARD),
-                    translator.localize(LocaleResources.CONNECTION_QUIT),
+                    translator.localize(LocaleResources.CONNECTION_WIZARD).getContents(),
+                    translator.localize(LocaleResources.CONNECTION_QUIT).getContents(),
             };
             int n = JOptionPane
                     .showOptionDialog(
                             null,
-                            translator.localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_DESCRIPTION),
-                            translator.localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_TITLE),
+                            translator.localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_DESCRIPTION).getContents(),
+                            translator.localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_TITLE).getContents(),
                             JOptionPane.OK_CANCEL_OPTION,
                             JOptionPane.ERROR_MESSAGE, null, options,
                             options[0]);
@@ -313,8 +313,8 @@
                 } else {
                     JOptionPane.showMessageDialog(
                             null,
-                            translator.localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_DESCRIPTION),
-                            translator.localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_TITLE),
+                            translator.localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_DESCRIPTION).getContents(),
+                            translator.localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_TITLE).getContents(),
                             JOptionPane.ERROR_MESSAGE);
                     shutdown.countDown();
                 }
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindow.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindow.java	Thu May 02 10:58:20 2013 -0600
@@ -104,10 +104,8 @@
 import com.redhat.thermostat.client.ui.ContextAction;
 import com.redhat.thermostat.client.ui.Decorator;
 import com.redhat.thermostat.client.ui.DecoratorProvider;
-import com.redhat.thermostat.client.ui.HostContextAction;
 import com.redhat.thermostat.client.ui.IconDescriptor;
 import com.redhat.thermostat.client.ui.MenuAction;
-import com.redhat.thermostat.client.ui.VMContextAction;
 import com.redhat.thermostat.common.ActionEvent;
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.common.ActionNotifier;
@@ -411,19 +409,19 @@
 
     private void setupMenus() {
 
-        JMenu fileMenu = new JMenu(translator.localize(LocaleResources.MENU_FILE));
+        JMenu fileMenu = new JMenu(translator.localize(LocaleResources.MENU_FILE).getContents());
         fileMenu.getPopupMenu().setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
         mainMenuBar.add(fileMenu);
 
-        JMenuItem fileExitMenu = new JMenuItem(translator.localize(LocaleResources.MENU_FILE_EXIT));
+        JMenuItem fileExitMenu = new JMenuItem(translator.localize(LocaleResources.MENU_FILE_EXIT).getContents());
         fileExitMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.CTRL_DOWN_MASK));
         fileExitMenu.addActionListener(shutdownAction);
         fileMenu.add(fileExitMenu);
 
-        JMenu editMenu = new JMenu(translator.localize(LocaleResources.MENU_EDIT));
+        JMenu editMenu = new JMenu(translator.localize(LocaleResources.MENU_EDIT).getContents());
         mainMenuBar.add(editMenu);
 
-        JMenuItem configureClientMenuItem = new JMenuItem(translator.localize(LocaleResources.MENU_EDIT_CONFIGURE_CLIENT));
+        JMenuItem configureClientMenuItem = new JMenuItem(translator.localize(LocaleResources.MENU_EDIT_CONFIGURE_CLIENT).getContents());
         configureClientMenuItem.setName("showClientConfig");
         configureClientMenuItem.addActionListener(new java.awt.event.ActionListener() {
             @Override
@@ -434,7 +432,7 @@
         editMenu.add(configureClientMenuItem);
 
         editMenu.addSeparator();
-        JMenuItem historyModeMenuItem = new JCheckBoxMenuItem(translator.localize(LocaleResources.MENU_EDIT_ENABLE_HISTORY_MODE));
+        JMenuItem historyModeMenuItem = new JCheckBoxMenuItem(translator.localize(LocaleResources.MENU_EDIT_ENABLE_HISTORY_MODE).getContents());
         historyModeMenuItem.setName("historyModeSwitch");
         historyModeMenuItem.setSelected(false);
         historyModeMenuItem.addActionListener(new java.awt.event.ActionListener() {
@@ -445,9 +443,9 @@
         });
         editMenu.add(historyModeMenuItem);
 
-        JMenu viewMenu = new JMenu(translator.localize(LocaleResources.MENU_VIEW));
+        JMenu viewMenu = new JMenu(translator.localize(LocaleResources.MENU_VIEW).getContents());
         mainMenuBar.add(viewMenu);
-        JMenuItem configureAgentMenuItem = new JMenuItem(translator.localize(LocaleResources.MENU_VIEW_AGENTS));
+        JMenuItem configureAgentMenuItem = new JMenuItem(translator.localize(LocaleResources.MENU_VIEW_AGENTS).getContents());
         configureAgentMenuItem.setName("showAgentConfig");
         configureAgentMenuItem.addActionListener(new java.awt.event.ActionListener() {
             @Override
@@ -457,11 +455,11 @@
         });
         viewMenu.add(configureAgentMenuItem);
 
-        JMenu helpMenu = new JMenu(translator.localize(LocaleResources.MENU_HELP));
+        JMenu helpMenu = new JMenu(translator.localize(LocaleResources.MENU_HELP).getContents());
         helpMenu.getPopupMenu().setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
         mainMenuBar.add(helpMenu);
 
-        JMenuItem helpAboutMenu = new JMenuItem(translator.localize(LocaleResources.MENU_HELP_ABOUT));
+        JMenuItem helpAboutMenu = new JMenuItem(translator.localize(LocaleResources.MENU_HELP_ABOUT).getContents());
         helpAboutMenu.addActionListener(new java.awt.event.ActionListener() {
             @Override
             public void actionPerformed(java.awt.event.ActionEvent e) {
@@ -659,12 +657,12 @@
                 HostRef hostRef = (HostRef) value;
                 String hostName = hostRef.getHostName();
                 String agentId = hostRef.getAgentId();
-                return translator.localize(LocaleResources.HOST_TOOLTIP, hostName, agentId);
+                return translator.localize(LocaleResources.HOST_TOOLTIP, hostName, agentId).getContents();
             } else if (value instanceof VmRef) {
                 VmRef vmRef = (VmRef) value;
                 String vmName = vmRef.getName();
                 String vmId = vmRef.getIdString();
-                return translator.localize(LocaleResources.VM_TOOLTIP, vmName, vmId);
+                return translator.localize(LocaleResources.VM_TOOLTIP, vmName, vmId).getContents();
             } else {
                 return null;
             }
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/AgentInformationDisplayFrame.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/AgentInformationDisplayFrame.java	Thu May 02 10:58:20 2013 -0600
@@ -75,8 +75,8 @@
     private static final Translate<LocaleResources> translate = LocaleResources.createLocalizer();
 
     private static final String[] BACKEND_TABLE_COLUMN_NAMES = new String[] {
-        translate.localize(LocaleResources.AGENT_INFO_BACKEND_NAME_COLUMN),
-        translate.localize(LocaleResources.AGENT_INFO_BACKEND_STATUS_COLUMN),
+        translate.localize(LocaleResources.AGENT_INFO_BACKEND_NAME_COLUMN).getContents(),
+        translate.localize(LocaleResources.AGENT_INFO_BACKEND_STATUS_COLUMN).getContents(),
     };
 
     private final CopyOnWriteArrayList<ActionListener<ConfigurationAction>> listeners = new CopyOnWriteArrayList<>();
@@ -110,10 +110,10 @@
         windowListener = new WindowClosingListener();
 
         frame = new JFrame();
-        frame.setTitle(translate.localize(LocaleResources.AGENT_INFO_WINDOW_TITLE));
+        frame.setTitle(translate.localize(LocaleResources.AGENT_INFO_WINDOW_TITLE).getContents());
         frame.addWindowListener(windowListener);
 
-        closeButton = new JButton(translate.localize(LocaleResources.BUTTON_CLOSE));
+        closeButton = new JButton(translate.localize(LocaleResources.BUTTON_CLOSE).getContents());
         closeButton.addActionListener(configurationComplete);
         closeButton.setName("close");
 
@@ -142,7 +142,7 @@
         JPanel agentListPanel = new JPanel();
         splitPane.setLeftComponent(agentListPanel);
 
-        JLabel agentLabel = new JLabel(translate.localize(LocaleResources.AGENT_INFO_AGENTS_LIST));
+        JLabel agentLabel = new JLabel(translate.localize(LocaleResources.AGENT_INFO_AGENTS_LIST).getContents());
 
         JScrollPane scrollPane = new JScrollPane();
 
@@ -167,7 +167,7 @@
         LabelField agentStartTimeLabel = new LabelField(translate.localize(LocaleResources.AGENT_INFO_AGENT_START_TIME_LABEL));
         LabelField agentStopTimeLabel = new LabelField(translate.localize(LocaleResources.AGENT_INFO_AGENT_STOP_TIME_LABEL));
 
-        String notAvailable = translate.localize(LocaleResources.INFORMATION_NOT_AVAILABLE);
+        String notAvailable = translate.localize(LocaleResources.INFORMATION_NOT_AVAILABLE).getContents();
 
         currentAgentName = new ValueField(notAvailable);
         currentAgentName.setName("agentName");
@@ -195,7 +195,7 @@
 
         JScrollPane backendsTableScollPane = new JScrollPane(backendsTable);
 
-        JLabel backendDescriptionLabel = new JLabel(translate.localize(LocaleResources.AGENT_INFO_BACKEND_DESCRIPTION_LABEL));
+        JLabel backendDescriptionLabel = new JLabel(translate.localize(LocaleResources.AGENT_INFO_BACKEND_DESCRIPTION_LABEL).getContents());
         backendDescription = new ValueField(notAvailable);
         backendDescription.setName("backendDescription");
 
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/ClientConfigurationPanel.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/ClientConfigurationPanel.java	Thu May 02 10:58:20 2013 -0600
@@ -62,16 +62,16 @@
     
     public ClientConfigurationPanel() {
         setBorder(new TitledBorder(null,
-                  translator.localize(LocaleResources.CLIENT_PREFS_CONNECTION),
+                  translator.localize(LocaleResources.CLIENT_PREFS_CONNECTION).getContents(),
                   TitledBorder.LEFT, TitledBorder.TOP, null, null));
 
-        JLabel storageURLText = new JLabel(translator.localize(LocaleResources.CLIENT_PREFS_STORAGE_URL));
+        JLabel storageURLText = new JLabel(translator.localize(LocaleResources.CLIENT_PREFS_STORAGE_URL).getContents());
         storageURLText.setName("");
         
         storageUrl.setColumns(10);
         storageUrl.setName("connectionUrl");
         
-        JLabel userNameText = new JLabel(translator.localize(LocaleResources.CLIENT_PREFS_STORAGE_USERNAME));
+        JLabel userNameText = new JLabel(translator.localize(LocaleResources.CLIENT_PREFS_STORAGE_USERNAME).getContents());
         userNameText.setName("userNameText");
         
         userName.setName("username");
@@ -83,7 +83,7 @@
         password.setName("password");
         password.setColumns(10);
         
-        saveEntitlements = new JCheckBox(translator.localize(LocaleResources.CLIENT_PREFS_STORAGE_SAVE_ENTITLEMENTS));
+        saveEntitlements = new JCheckBox(translator.localize(LocaleResources.CLIENT_PREFS_STORAGE_SAVE_ENTITLEMENTS).getContents());
         saveEntitlements.setName("saveEntitlements");
         saveEntitlements.setSelected(false);
 
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/ClientConfigurationSwing.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/ClientConfigurationSwing.java	Thu May 02 10:58:20 2013 -0600
@@ -94,7 +94,7 @@
             }
         });
 
-        dialog = new JDialog((Frame) null, translator.localize(LocaleResources.CLIENT_PREFS_WINDOW_TITLE));
+        dialog = new JDialog((Frame) null, translator.localize(LocaleResources.CLIENT_PREFS_WINDOW_TITLE).getContents());
         dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
         dialog.setContentPane(optionPane);
         dialog.addWindowListener(windowClosingListener);
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/HostInformationPanel.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/HostInformationPanel.java	Thu May 02 10:58:20 2013 -0600
@@ -46,6 +46,7 @@
 import com.redhat.thermostat.client.core.views.HostInformationView;
 import com.redhat.thermostat.client.core.views.UIComponent;
 import com.redhat.thermostat.client.swing.SwingComponent;
+import com.redhat.thermostat.common.locale.LocalizedString;
 
 public class HostInformationPanel extends HostInformationView implements SwingComponent {
 
@@ -63,13 +64,13 @@
     }
 
     @Override
-    public void addChildView(final String title, final UIComponent view) {
+    public void addChildView(final LocalizedString title, final UIComponent view) {
         if (view instanceof SwingComponent) {
             final SwingComponent component = (SwingComponent)view;
             SwingUtilities.invokeLater(new Runnable() {
                 @Override
                 public void run() {
-                    tabPane.insertTab(title, null, component.getUiComponent(), null, viewCount);
+                    tabPane.insertTab(title.getContents(), null, component.getUiComponent(), null, viewCount);
                     viewCount++;
                 }
                 
@@ -78,12 +79,12 @@
     }
 
     @Override
-    public void removeChildView(final String title) {
+    public void removeChildView(final LocalizedString title) {
         SwingUtilities.invokeLater(new Runnable() {
             @Override
             public void run() {
                 for (int i = 0; i < viewCount; i++) {
-                    if (tabPane.getTitleAt(i).equals(title)) {
+                    if (tabPane.getTitleAt(i).equals(title.getContents())) {
                         tabPane.remove(i);
                         return;
                     }
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/SummaryPanel.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/SummaryPanel.java	Thu May 02 10:58:20 2013 -0600
@@ -77,11 +77,11 @@
         visiblePanel = new JPanel();
         JLabel lblHomepanel = new SectionHeader(translator.localize(LocaleResources.HOME_PANEL_SECTION_SUMMARY));
 
-        JLabel lblTotalHosts = new JLabel(translator.localize(LocaleResources.HOME_PANEL_TOTAL_MACHINES));
+        JLabel lblTotalHosts = new JLabel(translator.localize(LocaleResources.HOME_PANEL_TOTAL_MACHINES).getContents());
 
         totalMonitoredHosts = new ValueField("");
 
-        JLabel lblTotal = new JLabel(translator.localize(LocaleResources.HOME_PANEL_TOTAL_JVMS));
+        JLabel lblTotal = new JLabel(translator.localize(LocaleResources.HOME_PANEL_TOTAL_JVMS).getContents());
 
         totalMonitoredVms = new ValueField("");
 
@@ -194,7 +194,7 @@
 
         private List<? extends Object> delegate;
 
-        private String emptyElement = translator.localize(LocaleResources.HOME_PANEL_NO_ISSUES);
+        private String emptyElement = translator.localize(LocaleResources.HOME_PANEL_NO_ISSUES).getContents();
 
         public IssuesListModel(List<? extends Object> actualList) {
             this.delegate = actualList;
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/VmInformationPanel.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/VmInformationPanel.java	Thu May 02 10:58:20 2013 -0600
@@ -45,6 +45,7 @@
 import com.redhat.thermostat.client.core.views.UIComponent;
 import com.redhat.thermostat.client.core.views.VmInformationView;
 import com.redhat.thermostat.client.swing.SwingComponent;
+import com.redhat.thermostat.common.locale.LocalizedString;
 
 public class VmInformationPanel extends VmInformationView implements SwingComponent {
 
@@ -62,10 +63,10 @@
     }
 
     @Override
-    public void addChildView(String title, UIComponent view) {
+    public void addChildView(LocalizedString title, UIComponent view) {
         if (view instanceof SwingComponent) {
             SwingComponent panel = (SwingComponent)view;
-            tabPane.insertTab(title, null, panel.getUiComponent(), null, tabCount);
+            tabPane.insertTab(title.getContents(), null, panel.getUiComponent(), null, tabCount);
             tabCount++;
         }
     }
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/ActionButtonTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/ActionButtonTest.java	Thu May 02 10:58:20 2013 -0600
@@ -59,6 +59,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import com.redhat.thermostat.common.locale.LocalizedString;
+
 @RunWith(CacioFESTRunner.class)
 public class ActionButtonTest {
 
@@ -119,7 +121,7 @@
                     }
                 };
 
-                ActionButton button = new ActionButton(icon, "Fluff");
+                ActionButton button = new ActionButton(icon, new LocalizedString("Fluff"));
                 button.setName("button");
                 header.addToolBarButton(button);
 
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/HeaderPanelTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/HeaderPanelTest.java	Thu May 02 10:58:20 2013 -0600
@@ -59,6 +59,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import com.redhat.thermostat.common.locale.LocalizedString;
+
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertEquals;
@@ -103,10 +105,10 @@
                 someIcon2 = new EmptyIcon(16, 16);
                 someIcon3 = new EmptyIcon(16, 16);
                 
-                ActionButton button1 = new ActionButton(someIcon1, "button1");
+                ActionButton button1 = new ActionButton(someIcon1, new LocalizedString("button1"));
                 button1.setName("button1");
                 
-                ActionButton button2 = new ActionButton(someIcon2, "button2");
+                ActionButton button2 = new ActionButton(someIcon2, new LocalizedString("button2"));
                 button2.setName("button2");
                 
                 ActionToggleButton toggle1 = new ActionToggleButton(someIcon3, "toggle1");
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/views/HostInformationPanelTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/views/HostInformationPanelTest.java	Thu May 02 10:58:20 2013 -0600
@@ -51,10 +51,10 @@
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import com.redhat.thermostat.client.core.views.BasicView;
 import com.redhat.thermostat.client.core.views.UIComponent;
 import com.redhat.thermostat.client.swing.TabbedPaneMatcher;
 import com.redhat.thermostat.client.swing.internal.views.HostInformationPanel;
+import com.redhat.thermostat.common.locale.LocalizedString;
 
 public class HostInformationPanelTest {
 
@@ -109,14 +109,14 @@
     public void testAddTwice() throws InvocationTargetException, InterruptedException {
         UIComponent mock1 = createHostInfoPanel();
 
-        panel.addChildView("foo1", mock1);
+        panel.addChildView(new LocalizedString("foo1"), mock1);
 
         // The panel in test has no views added so the matcher with a tab count > 0 works
         // in order to select the right panel.
         window.panel("panel").tabbedPane(new TabbedPaneMatcher(JTabbedPane.class)).requireTabTitles("foo1");
 
         UIComponent mock2 = createHostInfoPanel();
-        panel.addChildView("foo2", mock2);
+        panel.addChildView(new LocalizedString("foo2"), mock2);
 
         window.panel("panel").tabbedPane(new TabbedPaneMatcher(JTabbedPane.class)).requireTabTitles("foo1", "foo2");
     }
@@ -126,14 +126,14 @@
         UIComponent test1 = createHostInfoPanel();
         UIComponent test2 = createHostInfoPanel();
 
-        panel.addChildView("test1", test1);
-        panel.addChildView("test2", test2);
+        panel.addChildView(new LocalizedString("test1"), test1);
+        panel.addChildView(new LocalizedString("test2"), test2);
 
         // The panel in test has no views added so the matcher with a tab count > 0 works
         // in order to select the right panel.
         window.panel("panel").tabbedPane(new TabbedPaneMatcher(JTabbedPane.class)).requireTabTitles("test1", "test2");
 
-        panel.removeChildView("test1");
+        panel.removeChildView(new LocalizedString("test1"));
 
         window.panel("panel").tabbedPane(new TabbedPaneMatcher(JTabbedPane.class)).requireTabTitles("test2");
     }
--- a/common/core/src/main/java/com/redhat/thermostat/common/ApplicationInfo.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/common/core/src/main/java/com/redhat/thermostat/common/ApplicationInfo.java	Thu May 02 10:58:20 2013 -0600
@@ -55,6 +55,8 @@
     private Properties appInfo;
 
     private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
+
+    private static final String MISSING_INFO = t.localize(LocaleResources.MISSING_INFO).getContents();
     
     public ApplicationInfo() {
         appInfo = new Properties();
@@ -70,7 +72,7 @@
     }
 
     public String getName() {
-        return appInfo.getProperty("APP_NAME", t.localize(LocaleResources.MISSING_INFO));
+        return appInfo.getProperty("APP_NAME", MISSING_INFO);
     }
 
     public Version getVersion() {
@@ -82,27 +84,27 @@
     }
 
     public String getDescription() {
-        return t.localize(LocaleResources.APPLICATION_INFO_DESCRIPTION);
+        return t.localize(LocaleResources.APPLICATION_INFO_DESCRIPTION).getContents();
     }
 
     public String getReleaseDate() {
-        return appInfo.getProperty("APP_RELEASE_DATE", t.localize(LocaleResources.MISSING_INFO));
+        return appInfo.getProperty("APP_RELEASE_DATE", MISSING_INFO);
     }
 
     public String getCopyright() {
-        return appInfo.getProperty("APP_COPYRIGHT", t.localize(LocaleResources.MISSING_INFO));
+        return appInfo.getProperty("APP_COPYRIGHT", MISSING_INFO);
     }
 
     public String getLicenseSummary() {
-        return t.localize(LocaleResources.APPLICATION_INFO_LICENSE);
+        return t.localize(LocaleResources.APPLICATION_INFO_LICENSE).getContents();
     }
 
     public String getEmail() {
-        return appInfo.getProperty("APP_EMAIL", t.localize(LocaleResources.MISSING_INFO));
+        return appInfo.getProperty("APP_EMAIL", MISSING_INFO);
     }
 
     public String getWebsite() {
-        return appInfo.getProperty("APP_WEBSITE", t.localize(LocaleResources.MISSING_INFO));
+        return appInfo.getProperty("APP_WEBSITE", MISSING_INFO);
     }
 
 }
--- a/common/core/src/main/java/com/redhat/thermostat/common/Size.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/common/core/src/main/java/com/redhat/thermostat/common/Size.java	Thu May 02 10:58:20 2013 -0600
@@ -148,7 +148,7 @@
     @Override
     public String toString() {
         String[] parts = toStringParts();
-        return translator.localize(LocaleResources.VALUE_AND_UNIT, parts[0], parts[1]);
+        return translator.localize(LocaleResources.VALUE_AND_UNIT, parts[0], parts[1]).getContents();
     }
 
     /**
--- a/common/core/src/main/java/com/redhat/thermostat/common/Version.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/common/core/src/main/java/com/redhat/thermostat/common/Version.java	Thu May 02 10:58:20 2013 -0600
@@ -76,7 +76,7 @@
         ApplicationInfo appInfo = new ApplicationInfo();
         Translate<LocaleResources> t = LocaleResources.createLocalizer();
         String format = MessageFormat.format(
-                t.localize(LocaleResources.APPLICATION_VERSION_INFO),
+                t.localize(LocaleResources.APPLICATION_VERSION_INFO).getContents(),
                 appInfo.getName())
                 + " " + VERSION_NUMBER_FORMAT;
         return String.format(format, getMajor(), getMinor(), getMicro());
--- a/common/core/src/main/java/com/redhat/thermostat/common/cli/CommandException.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/common/core/src/main/java/com/redhat/thermostat/common/cli/CommandException.java	Thu May 02 10:58:20 2013 -0600
@@ -36,6 +36,8 @@
 
 package com.redhat.thermostat.common.cli;
 
+import com.redhat.thermostat.common.locale.LocalizedString;
+
 /**
  * An exception to be thrown by a {@link Command} upon implementation-defined
  * failure conditions.
@@ -44,21 +46,25 @@
 
     private static final long serialVersionUID = 3730368617641245016L;
 
-    public CommandException() {
-        super();
-    }
+    private LocalizedString localizedMessage;
 
-    public CommandException(String message) {
-        super(message);
+    public CommandException(LocalizedString message) {
+        super(message.getContents());
+        localizedMessage = message;
     }
 
     public CommandException(Throwable cause) {
         super(cause);
+        localizedMessage = new LocalizedString(cause.getLocalizedMessage());
     }
 
-    public CommandException(String message, Throwable cause) {
-        super(message, cause);
+    public CommandException(LocalizedString message, Throwable cause) {
+        super(message.getContents(), cause);
+        localizedMessage = message;
     }
 
+    public LocalizedString getTranslatedMessage() {
+        return localizedMessage;
+    }
 }
 
--- a/common/core/src/main/java/com/redhat/thermostat/common/config/Configuration.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/common/core/src/main/java/com/redhat/thermostat/common/config/Configuration.java	Thu May 02 10:58:20 2013 -0600
@@ -38,9 +38,13 @@
 
 import java.io.File;
 
+import com.redhat.thermostat.common.locale.LocaleResources;
+import com.redhat.thermostat.common.locale.Translate;
+
 public class Configuration {
 
     private static final String THERMOSTAT_USER_DIR = ".thermostat";
+    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
 
     private String home;
     private boolean printOsgiInfo = false;
@@ -54,7 +58,7 @@
         }
         
         if (home == null) {
-            throw new InvalidConfigurationException("THERMOSTAT_HOME not defined...");
+            throw new InvalidConfigurationException(t.localize(LocaleResources.ENV_NO_HOME));
         }
         this.home = home;
     }
--- a/common/core/src/main/java/com/redhat/thermostat/common/config/InvalidConfigurationException.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/common/core/src/main/java/com/redhat/thermostat/common/config/InvalidConfigurationException.java	Thu May 02 10:58:20 2013 -0600
@@ -36,6 +36,8 @@
 
 package com.redhat.thermostat.common.config;
 
+import com.redhat.thermostat.common.locale.LocalizedString;
+
 
 public class InvalidConfigurationException extends RuntimeException {
 
@@ -44,13 +46,17 @@
     public InvalidConfigurationException() {
         super();
     }
-    
+
     public InvalidConfigurationException(String message) {
         super(message);
     }
     
-    public InvalidConfigurationException(String message, Throwable cause) {
-        super(message, cause);
+    public InvalidConfigurationException(LocalizedString message) {
+        this(message.getContents());
+    }
+    
+    public InvalidConfigurationException(LocalizedString message, Throwable cause) {
+        super(message.getContents(), cause);
     }
     
     public InvalidConfigurationException(Throwable cause) {
--- a/common/core/src/main/java/com/redhat/thermostat/common/locale/LocaleResources.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/common/core/src/main/java/com/redhat/thermostat/common/locale/LocaleResources.java	Thu May 02 10:58:20 2013 -0600
@@ -48,6 +48,10 @@
 
     USERNAME_PROMPT,
     PASSWORD_PROMPT,
+
+    LOGGING_PROPERTIES_ISSUE,
+
+    ENV_NO_HOME,
     ;
 
     public static final String RESOURCE_BUNDLE =
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/main/java/com/redhat/thermostat/common/locale/LocalizedString.java	Thu May 02 10:58:20 2013 -0600
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2012, 2013 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.locale;
+
+public final class LocalizedString {
+
+    private final String contents;
+
+    /**
+     * Create a {@link LocalizedString} with pre-translated contents.  This
+     * constructor is public for testing purposes, production code should use
+     * {@link Translate#localize(? extends Enum)} instead.
+     *
+     * @param contents The pre-translated contents for the new {@link LocalizedString}
+     */
+    public LocalizedString(String contents) {
+        this.contents = contents;
+    }
+
+    public String getContents() {
+        return contents;
+    }
+}
--- a/common/core/src/main/java/com/redhat/thermostat/common/locale/Translate.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/common/core/src/main/java/com/redhat/thermostat/common/locale/Translate.java	Thu May 02 10:58:20 2013 -0600
@@ -52,12 +52,12 @@
         this.resourceBundle = resourceBundle;
     }
 
-    public String localize(T toTranslate) {
-        return resourceBundle.getString(toTranslate.name());
+    public LocalizedString localize(T toTranslate) {
+        return new LocalizedString(resourceBundle.getString(toTranslate.name()));
     }
 
-    public String localize(T toTranslate, String... params) {
-        return MessageFormat.format(localize(toTranslate), (Object[]) params);
+    public LocalizedString localize(T toTranslate, String... params) {
+        return new LocalizedString(MessageFormat.format(localize(toTranslate).getContents(), (Object[]) params));
     }
 }
 
--- a/common/core/src/main/java/com/redhat/thermostat/common/tools/StorageAuthInfoGetter.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/common/core/src/main/java/com/redhat/thermostat/common/tools/StorageAuthInfoGetter.java	Thu May 02 10:58:20 2013 -0600
@@ -69,7 +69,7 @@
      * @throws IOException 
      */
     public String getUserName(String url) throws IOException {
-        String prompt = t.localize(LocaleResources.USERNAME_PROMPT, url);
+        String prompt = t.localize(LocaleResources.USERNAME_PROMPT, url).getContents();
         String name = reader.readLine(prompt);
         return name;
     }
@@ -85,7 +85,7 @@
     public char[] getPassword(String url) throws IOException {
         char[] password = new char[PW_SIZE_INCREMENT];
         reader.setHistoryEnabled(false);
-        reader.print(t.localize(LocaleResources.PASSWORD_PROMPT, url));
+        reader.print(t.localize(LocaleResources.PASSWORD_PROMPT, url).getContents());
         reader.flush();
         Character oldEcho = reader.getEchoCharacter();
         reader.setEchoCharacter('\0');
--- a/common/core/src/main/java/com/redhat/thermostat/common/utils/LoggingUtils.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/common/core/src/main/java/com/redhat/thermostat/common/utils/LoggingUtils.java	Thu May 02 10:58:20 2013 -0600
@@ -49,6 +49,8 @@
 import com.redhat.thermostat.common.LogFormatter;
 import com.redhat.thermostat.common.config.Configuration;
 import com.redhat.thermostat.common.config.InvalidConfigurationException;
+import com.redhat.thermostat.common.locale.LocaleResources;
+import com.redhat.thermostat.common.locale.Translate;
 
 /**
  * A few helper functions to facilitate using loggers
@@ -61,6 +63,7 @@
     // package private for testing
     static final String ROOTNAME = "com.redhat.thermostat";
 
+    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
     private static final Logger root;
 
     private static final ConsoleHandler handler;
@@ -149,14 +152,14 @@
             // for the root logger.
             LogManager.getLogManager().readConfiguration(fis);
         } catch (SecurityException | IOException e) {
-            throw new InvalidConfigurationException("Could not read logging.properties", e);
+            throw new InvalidConfigurationException(t.localize(LocaleResources.LOGGING_PROPERTIES_ISSUE), e);
         }
         try (FileInputStream fis = new FileInputStream(loggingPropertiesFile)) {
             // Finally add handlers as specified in the property file, with
             // ConsoleHandler and level INFO as default
             configureLogging(getDefaultProps(), fis);
         } catch (SecurityException | IOException e) {
-            throw new InvalidConfigurationException("Could not read logging.properties", e);
+            throw new InvalidConfigurationException(t.localize(LocaleResources.LOGGING_PROPERTIES_ISSUE), e);
         }
     }
 
--- a/common/core/src/main/resources/com/redhat/thermostat/common/locale/strings.properties	Thu Apr 25 17:27:42 2013 -0600
+++ b/common/core/src/main/resources/com/redhat/thermostat/common/locale/strings.properties	Thu May 02 10:58:20 2013 -0600
@@ -9,4 +9,8 @@
 
 # Parameters for prompts should be storage URL.
 USERNAME_PROMPT = Please enter username for storage at {0}:
-PASSWORD_PROMPT = Please enter password for storage at {0}:
\ No newline at end of file
+PASSWORD_PROMPT = Please enter password for storage at {0}:
+
+LOGGING_PROPERTIES_ISSUE = Could not read logging.properties
+
+ENV_NO_HOME = THERMOSTAT_HOME not defined...
--- a/common/core/src/test/java/com/redhat/thermostat/common/ApplicationInfoTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/common/core/src/test/java/com/redhat/thermostat/common/ApplicationInfoTest.java	Thu May 02 10:58:20 2013 -0600
@@ -60,7 +60,7 @@
     @Test
     public void testProperties() {
         ApplicationInfo appInfo = new ApplicationInfo();
-        assertFalse(appInfo.getName().compareTo(LocaleResources.createLocalizer().localize(LocaleResources.MISSING_INFO)) == 0);
+        assertFalse(appInfo.getName().compareTo(LocaleResources.createLocalizer().localize(LocaleResources.MISSING_INFO).getContents()) == 0);
     }
 
     @After
--- a/common/core/src/test/java/com/redhat/thermostat/common/VersionTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/common/core/src/test/java/com/redhat/thermostat/common/VersionTest.java	Thu May 02 10:58:20 2013 -0600
@@ -165,7 +165,7 @@
     private String createFormat() {
         ApplicationInfo appInfo = new ApplicationInfo();
         String format = MessageFormat.format(
-                LocaleResources.createLocalizer().localize(LocaleResources.APPLICATION_VERSION_INFO),
+                LocaleResources.createLocalizer().localize(LocaleResources.APPLICATION_VERSION_INFO).getContents(),
                 appInfo.getName())
                 + " " + Version.VERSION_NUMBER_FORMAT;
         return format;
--- a/common/core/src/test/java/com/redhat/thermostat/common/cli/CommandExceptionTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/common/core/src/test/java/com/redhat/thermostat/common/cli/CommandExceptionTest.java	Thu May 02 10:58:20 2013 -0600
@@ -41,18 +41,13 @@
 import org.junit.Test;
 
 import com.redhat.thermostat.common.cli.CommandException;
+import com.redhat.thermostat.common.locale.LocalizedString;
 
 public class CommandExceptionTest {
 
     @Test
-    public void testDefaultConstructor() {
-        CommandException ce = new CommandException();
-        verifyMessageAndCause(ce, null, null);
-    }
-
-    @Test
     public void testMessageConstructor() {
-        CommandException ce = new CommandException("test");
+        CommandException ce = new CommandException(new LocalizedString("test"));
         verifyMessageAndCause(ce, "test", null);
     }
 
@@ -66,7 +61,7 @@
     @Test
     public void testCombinedConstructor() {
         Exception cause = new Exception("test fluff");
-        CommandException ce = new CommandException("test", cause);
+        CommandException ce = new CommandException(new LocalizedString("test"), cause);
         verifyMessageAndCause(ce, "test", cause);
     }
 
--- a/common/core/src/test/java/com/redhat/thermostat/common/locale/TranslateTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/common/core/src/test/java/com/redhat/thermostat/common/locale/TranslateTest.java	Thu May 02 10:58:20 2013 -0600
@@ -72,7 +72,7 @@
 
         Translate<TestStrings> translate = new Translate<>(resources, TestStrings.class);
 
-        assertEquals("Localized String", translate.localize(TestStrings.SIMPLE_STRING));
+        assertEquals("Localized String", translate.localize(TestStrings.SIMPLE_STRING).getContents());
     }
 
     @Test
@@ -81,7 +81,7 @@
 
         Translate<TestStrings> translate = new Translate<>(resources, TestStrings.class);
 
-        assertEquals("Parameter: FOO", translate.localize(TestStrings.STRING_WITH_PARAMETER, "FOO"));
+        assertEquals("Parameter: FOO", translate.localize(TestStrings.STRING_WITH_PARAMETER, "FOO").getContents());
 
     }
 }
--- a/common/test/pom.xml	Thu Apr 25 17:27:42 2013 -0600
+++ b/common/test/pom.xml	Thu May 02 10:58:20 2013 -0600
@@ -78,7 +78,7 @@
             <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
             <Bundle-SymbolicName>com.redhat.thermostat.common.test</Bundle-SymbolicName>
             <Export-Package>
-              com.redhat.thermostat.testutils
+              com.redhat.thermostat.testutils,
             </Export-Package>
             <!-- Do not autogenerate uses clauses in Manifests -->
             <_nouses>true</_nouses>
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/RecentTimeSeriesChartComposite.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/RecentTimeSeriesChartComposite.java	Thu May 02 10:58:20 2013 -0600
@@ -131,7 +131,7 @@
         container.setLayout(topLayout);
         
         Label prompt = new Label(container, SWT.NONE);
-        prompt.setText(translator.localize(LocaleResources.CHART_DURATION_SELECTOR_LABEL));
+        prompt.setText(translator.localize(LocaleResources.CHART_DURATION_SELECTOR_LABEL).getContents());
 
         durationSelector = new Text(container, SWT.BORDER);
         durationSelector.setData(ThermostatConstants.TEST_TAG, TEST_ID_DURATION_TEXT);
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostCpuView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostCpuView.java	Thu May 02 10:58:20 2013 -0600
@@ -65,6 +65,7 @@
 import com.redhat.thermostat.host.cpu.client.core.HostCpuView;
 import com.redhat.thermostat.host.cpu.client.locale.LocaleResources;
 import com.redhat.thermostat.client.ui.ChartColors;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.eclipse.SWTComponent;
 import com.redhat.thermostat.eclipse.ThermostatConstants;
@@ -104,14 +105,14 @@
                 stdFont.getFontData()[0].getName(),
                 stdFont.getFontData()[0].getHeight(), SWT.BOLD);
         
-        summaryLabel.setText(translator.localize(LocaleResources.HOST_CPU_SECTION_OVERVIEW));
+        summaryLabel.setText(translator.localize(LocaleResources.HOST_CPU_SECTION_OVERVIEW).getContents());
         summaryLabel.setFont(boldFont);
         
         Composite detailsTop = new Composite(parent, SWT.NONE);
         detailsTop.setLayout(new GridLayout(3, false));
         
         Label cpuModelLabel = new Label(detailsTop, SWT.TRAIL);
-        cpuModelLabel.setText(translator.localize(LocaleResources.HOST_INFO_CPU_MODEL));
+        cpuModelLabel.setText(translator.localize(LocaleResources.HOST_INFO_CPU_MODEL).getContents());
         GridData hIndentLayoutData = new GridData();
         hIndentLayoutData.horizontalIndent = H_INDENT;
         cpuModelLabel.setLayoutData(hIndentLayoutData);
@@ -124,7 +125,7 @@
         cpuModel.setText("Unknown");
         
         Label cpuCountLabel = new Label(detailsTop, SWT.TRAIL);
-        cpuCountLabel.setText(translator.localize(LocaleResources.HOST_INFO_CPU_COUNT));
+        cpuCountLabel.setText(translator.localize(LocaleResources.HOST_INFO_CPU_COUNT).getContents());
         cpuCountLabel.setLayoutData(hIndentLayoutData);
         
         Label cpuCountSpacer = new Label(detailsTop, SWT.NONE);
@@ -148,8 +149,8 @@
     
     private JFreeChart createCpuChart() {
         JFreeChart chart = ChartFactory.createTimeSeriesChart(null,
-                translator.localize(LocaleResources.HOST_CPU_USAGE_CHART_TIME_LABEL),
-                translator.localize(LocaleResources.HOST_CPU_USAGE_CHART_VALUE_LABEL),
+                translator.localize(LocaleResources.HOST_CPU_USAGE_CHART_TIME_LABEL).getContents(),
+                translator.localize(LocaleResources.HOST_CPU_USAGE_CHART_VALUE_LABEL).getContents(),
                 datasetCollection, false, false, false);
 
         chart.getPlot().setBackgroundPaint(new Color(255, 255, 255, 0));
@@ -182,21 +183,22 @@
     }
 
     @Override
-    public void addCpuUsageChart(final int cpuIndex, final String humanReadableName) {
+    public void addCpuUsageChart(final int cpuIndex, final LocalizedString name) {
         EventQueue.invokeLater(new Runnable() {
 
             @Override
             public void run() {
-                TimeSeries series = new TimeSeries(humanReadableName);
+                String theName = name.getContents();
+                TimeSeries series = new TimeSeries(theName);
                 Color color = ChartColors.getColor(colors.size());
-                colors.put(humanReadableName, color);
+                colors.put(theName, color);
 
                 datasets.put(cpuIndex, series);
                 datasetCollection.addSeries(series);
 
                 updateColors();
 
-                addLegendItem(humanReadableName, color);
+                addLegendItem(theName, color);
             }
         });
     }
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostMemoryView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostMemoryView.java	Thu May 02 10:58:20 2013 -0600
@@ -71,6 +71,7 @@
 import com.redhat.thermostat.host.memory.client.locale.LocaleResources;
 import com.redhat.thermostat.client.ui.ChartColors;
 import com.redhat.thermostat.common.Size;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.eclipse.SWTComponent;
 import com.redhat.thermostat.eclipse.ThermostatConstants;
@@ -112,14 +113,14 @@
                 stdFont.getFontData()[0].getName(),
                 stdFont.getFontData()[0].getHeight(), SWT.BOLD);
         
-        summaryLabel.setText(translator.localize(LocaleResources.HOST_MEMORY_SECTION_OVERVIEW));
+        summaryLabel.setText(translator.localize(LocaleResources.HOST_MEMORY_SECTION_OVERVIEW).getContents());
         summaryLabel.setFont(boldFont);
         
         Composite detailsTop = new Composite(parent, SWT.NONE);
         detailsTop.setLayout(new GridLayout(3, false));
         
         Label cpuModelLabel = new Label(detailsTop, SWT.TRAIL);
-        cpuModelLabel.setText(translator.localize(LocaleResources.HOST_INFO_MEMORY_TOTAL));
+        cpuModelLabel.setText(translator.localize(LocaleResources.HOST_INFO_MEMORY_TOTAL).getContents());
         GridData hIndentLayoutData = new GridData();
         hIndentLayoutData.horizontalIndent = H_INDENT;
         cpuModelLabel.setLayoutData(hIndentLayoutData);
@@ -160,8 +161,8 @@
 
         JFreeChart chart = ChartFactory.createTimeSeriesChart(
                 null, // Title
-                translator.localize(LocaleResources.HOST_MEMORY_CHART_TIME_LABEL), // x-axis Label
-                translator.localize(LocaleResources.HOST_MEMORY_CHART_SIZE_LABEL, Size.Unit.MiB.name()), // y-axis Label
+                translator.localize(LocaleResources.HOST_MEMORY_CHART_TIME_LABEL).getContents(), // x-axis Label
+                translator.localize(LocaleResources.HOST_MEMORY_CHART_SIZE_LABEL, Size.Unit.MiB.name()).getContents(), // y-axis Label
                 memoryCollection, // Dataset
                 false, // Show Legend
                 false, // Use tooltips
@@ -189,7 +190,7 @@
     }
     
     @Override
-    public void addMemoryChart(final String tag, final String humanReadableName) {
+    public void addMemoryChart(final String tag, final LocalizedString name) {
         EventQueue.invokeLater(new Runnable() {
             @Override
             public void run() {
@@ -198,7 +199,7 @@
                 TimeSeries series = new TimeSeries(tag);
                 dataset.put(tag, series);
 
-                addLegendItem(tag, humanReadableName);
+                addLegendItem(tag, name.getContents());
                 
                 updateColors();
             }
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTVmCpuView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTVmCpuView.java	Thu May 02 10:58:20 2013 -0600
@@ -81,8 +81,8 @@
     private JFreeChart createCpuChart() {
         JFreeChart chart = ChartFactory.createTimeSeriesChart(
                 null,
-                translator.localize(LocaleResources.VM_CPU_CHART_TIME_LABEL),
-                translator.localize(LocaleResources.VM_CPU_CHART_LOAD_LABEL),
+                translator.localize(LocaleResources.VM_CPU_CHART_TIME_LABEL).getContents(),
+                translator.localize(LocaleResources.VM_CPU_CHART_LOAD_LABEL).getContents(),
                 data,
                 false, false, false);
 
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTVmGcView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTVmGcView.java	Thu May 02 10:58:20 2013 -0600
@@ -64,6 +64,7 @@
 import org.jfree.data.xy.IntervalXYDataset;
 
 import com.redhat.thermostat.client.ui.SampledDataset;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.eclipse.SWTComponent;
 import com.redhat.thermostat.storage.model.IntervalTimeData;
@@ -88,13 +89,13 @@
     }
 
     @Override
-    public void addChart(final String tag, final String title, final String units) {
+    public void addChart(final String tag, final LocalizedString title, final String units) {
         EventQueue.invokeLater(new Runnable() {
             @Override
             public void run() {
                 SampledDataset newData = new SampledDataset();
                 dataset.put(tag, newData);
-                Composite subPanel = createCollectorDetailsPanel(tag, newData, title, units);
+                Composite subPanel = createCollectorDetailsPanel(tag, newData, title.getContents(), units);
                 subPanels.put(tag, subPanel);
             }
         });
@@ -143,8 +144,8 @@
         // Create chart
         final JFreeChart chart = ChartFactory.createHistogram(
             null,
-            translator.localize(LocaleResources.VM_GC_COLLECTOR_CHART_REAL_TIME_LABEL),
-            translator.localize(LocaleResources.VM_GC_COLLECTOR_CHART_GC_TIME_LABEL, units),
+            translator.localize(LocaleResources.VM_GC_COLLECTOR_CHART_REAL_TIME_LABEL).getContents(),
+            translator.localize(LocaleResources.VM_GC_COLLECTOR_CHART_GC_TIME_LABEL, units).getContents(),
             collectorData,
             PlotOrientation.VERTICAL,
             false,
--- a/eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/src/com/redhat/thermostat/eclipse/chart/vmclassstat/SWTVmClassStatView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/src/com/redhat/thermostat/eclipse/chart/vmclassstat/SWTVmClassStatView.java	Thu May 02 10:58:20 2013 -0600
@@ -77,8 +77,8 @@
         
         chart = ChartFactory.createTimeSeriesChart(
                 null,
-                translator.localize(LocaleResources.VM_CLASSES_CHART_REAL_TIME_LABEL),
-                translator.localize(LocaleResources.VM_CLASSES_CHART_LOADED_CLASSES_LABEL),
+                translator.localize(LocaleResources.VM_CLASSES_CHART_REAL_TIME_LABEL).getContents(),
+                translator.localize(LocaleResources.VM_CLASSES_CHART_LOADED_CLASSES_LABEL).getContents(),
                 dataset,
                 false, false, false);
         
--- a/eclipse/com.redhat.thermostat.eclipse.test.ui/META-INF/MANIFEST.MF	Thu Apr 25 17:27:42 2013 -0600
+++ b/eclipse/com.redhat.thermostat.eclipse.test.ui/META-INF/MANIFEST.MF	Thu May 02 10:58:20 2013 -0600
@@ -13,6 +13,7 @@
 Import-Package: com.redhat.thermostat.client.core.views,
  com.redhat.thermostat.client.ui,
  com.redhat.thermostat.common,
+ com.redhat.thermostat.common.locale,
  com.redhat.thermostat.eclipse,
  com.redhat.thermostat.eclipse.chart.common,
  com.redhat.thermostat.eclipse.chart.vmclassstat,
--- a/eclipse/com.redhat.thermostat.eclipse.test.ui/src/com/redhat/thermostat/eclipse/test/ui/SWTHostCpuViewTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/eclipse/com.redhat.thermostat.eclipse.test.ui/src/com/redhat/thermostat/eclipse/test/ui/SWTHostCpuViewTest.java	Thu May 02 10:58:20 2013 -0600
@@ -65,6 +65,7 @@
 import com.redhat.thermostat.client.core.views.BasicView.Action;
 import com.redhat.thermostat.common.ActionEvent;
 import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.eclipse.ThermostatConstants;
 import com.redhat.thermostat.eclipse.chart.common.SWTHostCpuView;
 import com.redhat.thermostat.storage.model.DiscreteTimeData;
@@ -172,7 +173,7 @@
 
     private void addSeries(int seriesIndex, String humanReadableName,
             final int numSeries) {
-        view.addCpuUsageChart(seriesIndex, humanReadableName);
+        view.addCpuUsageChart(seriesIndex, new LocalizedString(humanReadableName));
 
         bot.waitUntil(new DefaultCondition() {
 
--- a/eclipse/com.redhat.thermostat.eclipse.test.ui/src/com/redhat/thermostat/eclipse/test/ui/SWTHostMemoryViewTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/eclipse/com.redhat.thermostat.eclipse.test.ui/src/com/redhat/thermostat/eclipse/test/ui/SWTHostMemoryViewTest.java	Thu May 02 10:58:20 2013 -0600
@@ -71,6 +71,7 @@
 import com.redhat.thermostat.client.core.views.BasicView.Action;
 import com.redhat.thermostat.common.ActionEvent;
 import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.eclipse.ThermostatConstants;
 import com.redhat.thermostat.eclipse.chart.common.SWTHostMemoryView;
 import com.redhat.thermostat.host.memory.client.core.HostMemoryView.GraphVisibilityChangeListener;
@@ -514,7 +515,7 @@
     }
 
     private void addSeries(final String tag, String humanReadableName) {
-        view.addMemoryChart(tag, humanReadableName);
+        view.addMemoryChart(tag, new LocalizedString(humanReadableName));
 
         // Wait until series added
         bot.waitUntil(new DefaultCondition() {
--- a/eclipse/com.redhat.thermostat.eclipse.test.ui/src/com/redhat/thermostat/eclipse/test/ui/SWTVmGcViewTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/eclipse/com.redhat.thermostat.eclipse.test.ui/src/com/redhat/thermostat/eclipse/test/ui/SWTVmGcViewTest.java	Thu May 02 10:58:20 2013 -0600
@@ -62,6 +62,7 @@
 import com.redhat.thermostat.client.core.views.BasicView.Action;
 import com.redhat.thermostat.common.ActionEvent;
 import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.eclipse.chart.common.SWTVmGcView;
 import com.redhat.thermostat.storage.model.IntervalTimeData;
 
@@ -110,7 +111,7 @@
     }
 
     private void addChart(final String tag, String name) {
-        view.addChart(tag, name, "ms");
+        view.addChart(tag, new LocalizedString(name), "ms");
         
         bot.waitUntil(new DefaultCondition() {
             
--- a/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/views/SWTHostOverviewView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/views/SWTHostOverviewView.java	Thu May 02 10:58:20 2013 -0600
@@ -91,7 +91,7 @@
         // Basics
         Label lblBasics = new Label(top, SWT.NONE);
         lblBasics.setText(translator
-                .localize(LocaleResources.HOST_OVERVIEW_SECTION_BASICS));
+                .localize(LocaleResources.HOST_OVERVIEW_SECTION_BASICS).getContents());
         Font stdFont = lblBasics.getFont();
         Font boldFont = new Font(stdFont.getDevice(),
                 stdFont.getFontData()[0].getName(),
@@ -104,7 +104,7 @@
                 false));
         Label lblHostName = new Label(basicsComps, SWT.NONE);
         lblHostName.setText(translator
-                .localize(LocaleResources.HOST_INFO_HOSTNAME));
+                .localize(LocaleResources.HOST_INFO_HOSTNAME).getContents());
         GridData hostNameGridData = new GridData(SWT.FILL, SWT.CENTER, false,
                 false);
         hostNameGridData.widthHint = FIRST_COLUMN_WIDTH;
@@ -117,7 +117,7 @@
         // Hardware
         Label lblHardware = new Label(top, SWT.NONE);
         lblHardware.setText(translator
-                .localize(LocaleResources.HOST_OVERVIEW_SECTION_HARDWARE));
+                .localize(LocaleResources.HOST_OVERVIEW_SECTION_HARDWARE).getContents());
         lblHardware.setFont(boldFont);
         Composite hardwareComps = new Composite(top, SWT.NONE);
         hardwareComps.setLayout(gridlayout);
@@ -125,7 +125,7 @@
                 false));
         Label lblProcModel = new Label(hardwareComps, SWT.NONE);
         lblProcModel.setText(translator
-                .localize(LocaleResources.HOST_INFO_CPU_MODEL));
+                .localize(LocaleResources.HOST_INFO_CPU_MODEL).getContents());
         GridData procModelGridData = new GridData(SWT.FILL, SWT.CENTER, false,
                 false);
         procModelGridData.widthHint = FIRST_COLUMN_WIDTH;
@@ -137,7 +137,7 @@
                 .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
         Label lblProcCount = new Label(hardwareComps, SWT.NONE);
         lblProcCount.setText(translator
-                .localize(LocaleResources.HOST_INFO_CPU_COUNT));
+                .localize(LocaleResources.HOST_INFO_CPU_COUNT).getContents());
         GridData procCountGridData = new GridData(SWT.FILL, SWT.CENTER, false,
                 false);
         procCountGridData.widthHint = FIRST_COLUMN_WIDTH;
@@ -149,7 +149,7 @@
                 false));
         Label lblTotalMemory = new Label(hardwareComps, SWT.NONE);
         lblTotalMemory.setText(translator
-                .localize(LocaleResources.HOST_INFO_MEMORY_TOTAL));
+                .localize(LocaleResources.HOST_INFO_MEMORY_TOTAL).getContents());
         GridData totalMemGridData = new GridData(SWT.FILL, SWT.CENTER, false,
                 false);
         totalMemGridData.widthHint = FIRST_COLUMN_WIDTH;
@@ -161,7 +161,7 @@
                 false));
         Label lblNetwork = new Label(hardwareComps, SWT.NONE);
         lblNetwork.setText(translator
-                .localize(LocaleResources.HOST_INFO_NETWORK));
+                .localize(LocaleResources.HOST_INFO_NETWORK).getContents());
         GridData networkLayout = new GridData(SWT.FILL, SWT.TOP, false, false);
         networkLayout.widthHint = FIRST_COLUMN_WIDTH;
         lblNetwork.setLayoutData(networkLayout);
@@ -172,7 +172,7 @@
         // Software
         Label lblSoftware = new Label(top, SWT.NONE);
         lblSoftware.setText(translator
-                .localize(LocaleResources.HOST_OVERVIEW_SECTION_SOFTWARE));
+                .localize(LocaleResources.HOST_OVERVIEW_SECTION_SOFTWARE).getContents());
         lblSoftware.setFont(boldFont);
         Composite softwareComps = new Composite(top, SWT.NONE);
         softwareComps.setLayout(gridlayout);
@@ -180,7 +180,7 @@
                 false));
         Label lblOsName = new Label(softwareComps, SWT.NONE);
         lblOsName.setText(translator
-                .localize(LocaleResources.HOST_INFO_OS_NAME));
+                .localize(LocaleResources.HOST_INFO_OS_NAME).getContents());
         GridData osNameGridData = new GridData(SWT.FILL, SWT.CENTER, false,
                 false);
         osNameGridData.widthHint = FIRST_COLUMN_WIDTH;
@@ -191,7 +191,7 @@
         osName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
         Label lblKernel = new Label(softwareComps, SWT.NONE);
         lblKernel.setText(translator
-                .localize(LocaleResources.HOST_INFO_OS_KERNEL));
+                .localize(LocaleResources.HOST_INFO_OS_KERNEL).getContents());
         GridData osKernelGridData = new GridData(SWT.FILL, SWT.CENTER, false,
                 false);
         osKernelGridData.widthHint = FIRST_COLUMN_WIDTH;
--- a/host-cpu/client-core/src/main/java/com/redhat/thermostat/host/cpu/client/core/HostCpuView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/host-cpu/client-core/src/main/java/com/redhat/thermostat/host/cpu/client/core/HostCpuView.java	Thu May 02 10:58:20 2013 -0600
@@ -40,6 +40,7 @@
 
 import com.redhat.thermostat.client.core.views.BasicView;
 import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.storage.model.DiscreteTimeData;
 
 public abstract class HostCpuView extends BasicView implements UIComponent {
@@ -50,7 +51,7 @@
 
     public abstract void clearCpuUsageData();
 
-    public abstract void addCpuUsageChart(int cpuIndex, String humanReadableName);
+    public abstract void addCpuUsageChart(int cpuIndex, LocalizedString name);
 
     public abstract void addCpuUsageData(int cpuIndex, List<DiscreteTimeData<Double>> data);
 
--- a/host-cpu/client-core/src/main/java/com/redhat/thermostat/host/cpu/client/core/internal/HostCpuController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/host-cpu/client-core/src/main/java/com/redhat/thermostat/host/cpu/client/core/internal/HostCpuController.java	Thu May 02 10:58:20 2013 -0600
@@ -49,6 +49,7 @@
 import com.redhat.thermostat.common.NotImplementedException;
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.Timer.SchedulingType;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.host.cpu.client.core.HostCpuView;
 import com.redhat.thermostat.host.cpu.client.core.HostCpuViewProvider;
@@ -159,7 +160,7 @@
     }
 
     @Override
-    public String getLocalizedName() {
+    public LocalizedString getLocalizedName() {
         return translator.localize(LocaleResources.HOST_INFO_TAB_CPU);
     }
 
--- a/host-cpu/client-core/src/test/java/com/redhat/thermostat/host/cpu/client/core/internal/HostCpuControllerTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/host-cpu/client-core/src/test/java/com/redhat/thermostat/host/cpu/client/core/internal/HostCpuControllerTest.java	Thu May 02 10:58:20 2013 -0600
@@ -39,8 +39,8 @@
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isA;
 import static org.mockito.Matchers.isNotNull;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
@@ -62,6 +62,7 @@
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.Timer.SchedulingType;
 import com.redhat.thermostat.common.TimerFactory;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.host.cpu.client.core.HostCpuView;
 import com.redhat.thermostat.host.cpu.client.core.HostCpuViewProvider;
 import com.redhat.thermostat.host.cpu.client.core.internal.HostCpuController;
@@ -153,7 +154,7 @@
         verify(view).setCpuCount("12345");
         @SuppressWarnings("rawtypes")
         ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
-        verify(view).addCpuUsageChart(eq(0), anyString());
+        verify(view).addCpuUsageChart(eq(0), isA(LocalizedString.class));
         verify(view).addCpuUsageData(eq(0), captor.capture());
         List<DiscreteTimeData<Double>> cpuLoadData = captor.getValue();
         assertEquals(1, cpuLoadData.get(0).getTimeInMillis());
--- a/host-cpu/client-swing/src/main/java/com/redhat/thermostat/host/cpu/client/swing/internal/HostCpuPanel.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/host-cpu/client-swing/src/main/java/com/redhat/thermostat/host/cpu/client/swing/internal/HostCpuPanel.java	Thu May 02 10:58:20 2013 -0600
@@ -70,6 +70,7 @@
 import com.redhat.thermostat.client.ui.ChartColors;
 import com.redhat.thermostat.client.ui.RecentTimeSeriesChartController;
 import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.host.cpu.client.core.HostCpuView;
 import com.redhat.thermostat.host.cpu.client.locale.LocaleResources;
@@ -141,21 +142,22 @@
     }
 
     @Override
-    public void addCpuUsageChart(final int cpuIndex, final String humanReadableName) {
+    public void addCpuUsageChart(final int cpuIndex, final LocalizedString name) {
         SwingUtilities.invokeLater(new Runnable() {
             @Override
             public void run() {
-                TimeSeries series = new TimeSeries(humanReadableName);
+                String theName = name.getContents();
+                TimeSeries series = new TimeSeries(theName);
                 Color color = ChartColors.getColor(colors.size());
-                colors.put(humanReadableName, color);
+                colors.put(theName, color);
 
                 datasets.put(cpuIndex, series);
                 datasetCollection.addSeries(series);
 
                 updateColors();
 
-                JLabel label = createLabelWithLegend(humanReadableName, color);
-                labels.put(humanReadableName, label);
+                JLabel label = createLabelWithLegend(theName, color);
+                labels.put(theName, label);
 
                 legendPanel.add(label);
                 legendPanel.revalidate();
@@ -216,8 +218,8 @@
 
         chart = ChartFactory.createTimeSeriesChart(
                 null,
-                translator.localize(LocaleResources.HOST_CPU_USAGE_CHART_TIME_LABEL),
-                translator.localize(LocaleResources.HOST_CPU_USAGE_CHART_VALUE_LABEL),
+                translator.localize(LocaleResources.HOST_CPU_USAGE_CHART_TIME_LABEL).getContents(),
+                translator.localize(LocaleResources.HOST_CPU_USAGE_CHART_VALUE_LABEL).getContents(),
                 datasetCollection,
                 false, false, false);
 
--- a/host-memory/client-core/src/main/java/com/redhat/thermostat/host/memory/client/core/HostMemoryView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/host-memory/client-core/src/main/java/com/redhat/thermostat/host/memory/client/core/HostMemoryView.java	Thu May 02 10:58:20 2013 -0600
@@ -40,6 +40,7 @@
 
 import com.redhat.thermostat.client.core.views.BasicView;
 import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.storage.model.DiscreteTimeData;
 
 public abstract class HostMemoryView extends BasicView implements UIComponent {
@@ -52,7 +53,7 @@
 
     public abstract void setTotalMemory(String totalMemory);
 
-    public abstract void addMemoryChart(String tag, String humanReadableName);
+    public abstract void addMemoryChart(String tag, LocalizedString name);
 
     public abstract void removeMemoryChart(String tag);
 
--- a/host-memory/client-core/src/main/java/com/redhat/thermostat/host/memory/client/core/internal/HostMemoryController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/host-memory/client-core/src/main/java/com/redhat/thermostat/host/memory/client/core/internal/HostMemoryController.java	Thu May 02 10:58:20 2013 -0600
@@ -50,6 +50,7 @@
 import com.redhat.thermostat.common.Size;
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.Timer.SchedulingType;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.host.memory.client.core.HostMemoryView;
 import com.redhat.thermostat.host.memory.client.core.HostMemoryViewProvider;
@@ -181,7 +182,7 @@
     }
 
     @Override
-    public String getLocalizedName() {
+    public LocalizedString getLocalizedName() {
         return translator.localize(LocaleResources.HOST_INFO_TAB_MEMORY);
     }
 }
--- a/host-memory/client-swing/src/main/java/com/redhat/thermostat/host/memory/client/swing/internal/HostMemoryPanel.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/host-memory/client-swing/src/main/java/com/redhat/thermostat/host/memory/client/swing/internal/HostMemoryPanel.java	Thu May 02 10:58:20 2013 -0600
@@ -73,6 +73,7 @@
 import com.redhat.thermostat.client.ui.RecentTimeSeriesChartController;
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.common.Size;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.host.memory.client.core.HostMemoryView;
 import com.redhat.thermostat.host.memory.client.locale.LocaleResources;
@@ -130,7 +131,7 @@
     }
 
     @Override
-    public void addMemoryChart(final String tag, final String humanReadableName) {
+    public void addMemoryChart(final String tag, final LocalizedString name) {
         SwingUtilities.invokeLater(new Runnable() {
             @Override
             public void run() {
@@ -138,7 +139,7 @@
                 colors.put(tag, ChartColors.getColor(colorIndex));
                 TimeSeries series = new TimeSeries(tag);
                 dataset.put(tag, series);
-                JCheckBox newCheckBox = new JCheckBox(createLabelWithLegend(humanReadableName, colors.get(tag)));
+                JCheckBox newCheckBox = new JCheckBox(createLabelWithLegend(name, colors.get(tag)));
                 newCheckBox.setActionCommand(tag);
                 newCheckBox.setSelected(true);
                 newCheckBox.addActionListener(memoryCheckboxListener);
@@ -152,9 +153,9 @@
 
     }
 
-    private String createLabelWithLegend(String text, Color color) {
+    private String createLabelWithLegend(LocalizedString text, Color color) {
         String hexColor = "#" + Integer.toHexString(color.getRGB() & 0x00ffffff);
-        return "<html> <font color='" + hexColor + "'>\u2588</font> " + text + "</html>";
+        return "<html> <font color='" + hexColor + "'>\u2588</font> " + text.getContents() + "</html>";
     }
 
     @Override
@@ -301,8 +302,8 @@
     private JFreeChart createMemoryChart() {
         JFreeChart chart = ChartFactory.createTimeSeriesChart(
                 null, // Title
-                translator.localize(LocaleResources.HOST_MEMORY_CHART_TIME_LABEL), // x-axis Label
-                translator.localize(LocaleResources.HOST_MEMORY_CHART_SIZE_LABEL, Size.Unit.MiB.name()), // y-axis Label
+                translator.localize(LocaleResources.HOST_MEMORY_CHART_TIME_LABEL).getContents(), // x-axis Label
+                translator.localize(LocaleResources.HOST_MEMORY_CHART_SIZE_LABEL, Size.Unit.MiB.name()).getContents(), // y-axis Label
                 memoryCollection, // Dataset
                 false, // Show Legend
                 false, // Use tooltips
--- a/host-overview/client-core/src/main/java/com/redhat/thermostat/host/overview/client/core/internal/HostOverviewController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/host-overview/client-core/src/main/java/com/redhat/thermostat/host/overview/client/core/internal/HostOverviewController.java	Thu May 02 10:58:20 2013 -0600
@@ -51,6 +51,7 @@
 import com.redhat.thermostat.common.Size;
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.Timer.SchedulingType;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.host.overview.client.core.HostOverviewView;
 import com.redhat.thermostat.host.overview.client.core.HostOverviewViewProvider;
@@ -79,9 +80,9 @@
 
         final Vector<String> networkTableColumnVector;
         networkTableColumnVector = new Vector<String>();
-        networkTableColumnVector.add(translator.localize(LocaleResources.NETWORK_INTERFACE_COLUMN));
-        networkTableColumnVector.add(translator.localize(LocaleResources.NETWORK_IPV4_COLUMN));
-        networkTableColumnVector.add(translator.localize(LocaleResources.NETWORK_IPV6_COLUMN));
+        networkTableColumnVector.add(translator.localize(LocaleResources.NETWORK_INTERFACE_COLUMN).getContents());
+        networkTableColumnVector.add(translator.localize(LocaleResources.NETWORK_IPV4_COLUMN).getContents());
+        networkTableColumnVector.add(translator.localize(LocaleResources.NETWORK_IPV6_COLUMN).getContents());
 
         backgroundUpdateTimer = appSvc.getTimerFactory().createTimer();
         backgroundUpdateTimer.setAction(new Runnable() {
@@ -164,7 +165,7 @@
     }
 
     @Override
-    public String getLocalizedName() {
+    public LocalizedString getLocalizedName() {
         return translator.localize(LocaleResources.HOST_INFO_TAB_OVERVIEW);
     }
 }
--- a/integration-tests/src/test/java/com/redhat/thermostat/itest/CliTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/integration-tests/src/test/java/com/redhat/thermostat/itest/CliTest.java	Thu May 02 10:58:20 2013 -0600
@@ -188,7 +188,7 @@
         Spawn shell = spawnThermostat("shell", "--foo");
         shell.expectClose();
         String stdOut = shell.getCurrentStandardOutContents();
-        String expectedOut = "Unrecognized option: --foo\n"
+        String expectedOut = "Could not parse options: Unrecognized option: --foo\n"
                            + "usage: thermostat shell\n"
                            + "                  launches the Thermostat interactive shell\n"
                            + "thermostat shell\n\n";
--- a/killvm/client-swing/src/main/java/com/redhat/thermostat/killvm/client/internal/KillVMAction.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/killvm/client-swing/src/main/java/com/redhat/thermostat/killvm/client/internal/KillVMAction.java	Thu May 02 10:58:20 2013 -0600
@@ -76,12 +76,12 @@
 
     @Override
     public String getName() {
-        return t.localize(LocaleResources.ACTION_NAME);
+        return t.localize(LocaleResources.ACTION_NAME).getContents();
     }
 
     @Override
     public String getDescription() {
-        return t.localize(LocaleResources.ACTION_DESCRIPTION);
+        return t.localize(LocaleResources.ACTION_DESCRIPTION).getContents();
     }
 
     @Override
--- a/killvm/client-swing/src/main/java/com/redhat/thermostat/killvm/client/internal/SwingVMKilledListener.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/killvm/client-swing/src/main/java/com/redhat/thermostat/killvm/client/internal/SwingVMKilledListener.java	Thu May 02 10:58:20 2013 -0600
@@ -67,7 +67,7 @@
             logger.log(Level.SEVERE,
                     "Kill request error for VM ID "
                             + vmId);
-            showErrorMessage(t.localize(LocaleResources.KILL_ACTION_ERROR_RESPONSE_MSG, vmId));
+            showErrorMessage(t.localize(LocaleResources.KILL_ACTION_ERROR_RESPONSE_MSG, vmId).getContents());
             break;
         case OK:
             logger.log(Level.INFO,
--- a/killvm/client-swing/src/test/java/com/redhat/thermostat/killvm/client/locale/TranslateTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/killvm/client-swing/src/test/java/com/redhat/thermostat/killvm/client/locale/TranslateTest.java	Thu May 02 10:58:20 2013 -0600
@@ -69,7 +69,7 @@
     
     @Test
     public void testLocalizeWithoutArguments() {
-        String testString = t.localize(LocaleResources.MISSING_INFO);
+        String testString = t.localize(LocaleResources.MISSING_INFO).getContents();
         Assert.assertEquals("Missing Information", testString);
     }
     
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/CommandLineArgumentParseException.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/CommandLineArgumentParseException.java	Thu May 02 10:58:20 2013 -0600
@@ -37,14 +37,11 @@
 package com.redhat.thermostat.launcher.internal;
 
 import com.redhat.thermostat.common.cli.CommandException;
+import com.redhat.thermostat.common.locale.LocalizedString;
 
 public class CommandLineArgumentParseException extends CommandException {
 
-    public CommandLineArgumentParseException() {
-        super();
-    }
-
-    public CommandLineArgumentParseException(String message) {
+    public CommandLineArgumentParseException(LocalizedString message) {
         super(message);
     }
 
@@ -52,7 +49,7 @@
         super(cause);
     }
 
-    public CommandLineArgumentParseException(String message, Throwable cause) {
+    public CommandLineArgumentParseException(LocalizedString message, Throwable cause) {
         super(message, cause);
     }
 
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/CommandLineArgumentsParser.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/CommandLineArgumentsParser.java	Thu May 02 10:58:20 2013 -0600
@@ -49,6 +49,7 @@
 import org.apache.commons.cli.ParseException;
 
 import com.redhat.thermostat.common.cli.Arguments;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 
 public class CommandLineArgumentsParser {
@@ -71,21 +72,21 @@
             commandLine = parser.parse(options, args);
             return new CommandLineArguments(commandLine);
         } catch (MissingOptionException mae) {
-            String msg = createMissingOptionsMessage(mae);
-            throw new CommandLineArgumentParseException(msg.toString(), mae);
+            LocalizedString msg = createMissingOptionsMessage(mae);
+            throw new CommandLineArgumentParseException(msg, mae);
         } catch (ParseException e) {
-            throw new CommandLineArgumentParseException(e.getMessage(), e);
+            throw new CommandLineArgumentParseException(tr.localize(LocaleResources.PARSE_EXCEPTION_MESSAGE, e.getMessage()), e);
         }
     }
 
-    private String createMissingOptionsMessage(MissingOptionException mae) {
+    private LocalizedString createMissingOptionsMessage(MissingOptionException mae) {
         @SuppressWarnings("unchecked")
         List<String> missingOptions = mae.getMissingOptions();
         StringBuilder msg = new StringBuilder();
         if (missingOptions.size() == 1) {
-            msg.append(tr.localize(LocaleResources.MISSING_OPTION));
+            msg.append(tr.localize(LocaleResources.MISSING_OPTION).getContents());
         } else {
-            msg.append(tr.localize(LocaleResources.MISSING_OPTIONS));
+            msg.append(tr.localize(LocaleResources.MISSING_OPTIONS).getContents());
         }
         for (Iterator<String> i = missingOptions.iterator(); i.hasNext();) {
             String missingOption = i.next();
@@ -99,7 +100,8 @@
                 msg.append(", ");
             }
         }
-        return msg.toString();
+        // Workaround to create this (complex) localized string.
+        return new LocalizedString(msg.toString());
     }
 }
 
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/CommonOptions.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/CommonOptions.java	Thu May 02 10:58:20 2013 -0600
@@ -70,7 +70,7 @@
     static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
     
     static List<Option> getDbOptions() {
-        String dbUrlDesc = t.localize(LocaleResources.OPTION_DB_URL_DESC);
+        String dbUrlDesc = t.localize(LocaleResources.OPTION_DB_URL_DESC).getContents();
         Option dbUrlOption = new Option("d", DB_URL_ARG, true, dbUrlDesc);
         dbUrlOption.setRequired(false);
         dbUrlOption.setArgName(DB_URL_ARG);
@@ -80,7 +80,7 @@
     }
     
     static Option getLogOption() {
-        String desc = t.localize(LocaleResources.OPTION_LOG_LEVEL_DESC);
+        String desc = t.localize(LocaleResources.OPTION_LOG_LEVEL_DESC).getContents();
         Option logOption = new Option("l", LOG_LEVEL_ARG, true, desc);
         logOption.setRequired(false);
         logOption.setArgName(LOG_LEVEL_ARG);
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/HelpCommand.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/HelpCommand.java	Thu May 02 10:58:20 2013 -0600
@@ -73,7 +73,7 @@
         List<String> nonParsed = args.getNonOptionArguments();
 
         if (commandInfoSource == null) {
-            ctx.getConsole().getError().print(translator.localize(LocaleResources.CANNOT_GET_COMMAND_INFO));
+            ctx.getConsole().getError().print(translator.localize(LocaleResources.CANNOT_GET_COMMAND_INFO).getContents());
             return;
         }
 
@@ -85,7 +85,7 @@
     }
 
     private void printCommandSummaries(CommandContext ctx) {
-        ctx.getConsole().getOutput().print(translator.localize(LocaleResources.COMMAND_HELP_COMMAND_LIST_HEADER));
+        ctx.getConsole().getOutput().print(translator.localize(LocaleResources.COMMAND_HELP_COMMAND_LIST_HEADER).getContents());
 
         TableRenderer renderer = new TableRenderer(2, COMMANDS_COLUMNS_WIDTH);
 
@@ -108,7 +108,7 @@
             CommandInfo info = commandInfoSource.getCommandInfo(cmdName);
             printHelp(ctx, info);
         } catch (CommandInfoNotFoundException notFound) {
-            ctx.getConsole().getOutput().print(translator.localize(LocaleResources.UNKNOWN_COMMAND, cmdName));
+            ctx.getConsole().getOutput().print(translator.localize(LocaleResources.UNKNOWN_COMMAND, cmdName).getContents());
             printCommandSummaries(ctx);
         }
     }
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java	Thu May 02 10:58:20 2013 -0600
@@ -64,6 +64,7 @@
 import com.redhat.thermostat.common.cli.Console;
 import com.redhat.thermostat.common.config.ClientPreferences;
 import com.redhat.thermostat.common.config.InvalidConfigurationException;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.common.tools.ApplicationState;
 import com.redhat.thermostat.common.tools.StorageAuthInfoGetter;
@@ -232,7 +233,7 @@
         } catch (BundleException | IOException e) {
             // If this happens we definitely need to do something about it, and the
             // trace will be immeasurably helpful in figuring out what is wrong.
-            out.println(t.localize(LocaleResources.COMMAND_COULD_NOT_LOAD_BUNDLES, cmdName));
+            out.println(t.localize(LocaleResources.COMMAND_COULD_NOT_LOAD_BUNDLES, cmdName).getContents());
             e.printStackTrace(out);
             return;
         }
@@ -240,7 +241,7 @@
         Command cmd = commandSource.getCommand(cmdName);
 
         if (cmd == null) {
-            err.println(t.localize(LocaleResources.COMMAND_DESCRIBED_BUT_NOT_AVAILALBE, cmdName));
+            err.println(t.localize(LocaleResources.COMMAND_DESCRIBED_BUT_NOT_AVAILALBE, cmdName).getContents());
             return;
         }
 
@@ -270,13 +271,13 @@
     }
 
     private void outputBadShellContext(boolean inShell, PrintStream out, String cmd) {
-    	String message = null;
+    	LocalizedString message = null;
     	if (inShell) {
-    		message = t.localize(LocaleResources.COMMAND_AVAILABLE_OUTSIDE_SHELL_ONLY, cmd);
+            message = t.localize(LocaleResources.COMMAND_AVAILABLE_OUTSIDE_SHELL_ONLY, cmd);
     	} else {
-    		message = t.localize(LocaleResources.COMMAND_AVAILABLE_INSIDE_SHELL_ONLY, cmd);
+            message = t.localize(LocaleResources.COMMAND_AVAILABLE_INSIDE_SHELL_ONLY, cmd);
     	}
-    	out.println(message);
+    	out.println(message.getContents());
     }
 
     private void setupLogLevel(Arguments args) {
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LocaleResources.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LocaleResources.java	Thu May 02 10:58:20 2013 -0600
@@ -54,6 +54,7 @@
 
     MISSING_OPTION,
     MISSING_OPTIONS,
+    PARSE_EXCEPTION_MESSAGE,
 
     LAUNCHER_USER_AUTH_PROMPT_ERROR,
     LAUNCHER_MALFORMED_URL,
--- a/launcher/src/main/resources/com/redhat/thermostat/launcher/internal/strings.properties	Thu Apr 25 17:27:42 2013 -0600
+++ b/launcher/src/main/resources/com/redhat/thermostat/launcher/internal/strings.properties	Thu May 02 10:58:20 2013 -0600
@@ -14,6 +14,7 @@
 
 MISSING_OPTION = Missing required option: 
 MISSING_OPTIONS = Missing required options: 
+PARSE_EXCEPTION_MESSAGE = Could not parse options: {0}
 
 LAUNCHER_USER_AUTH_PROMPT_ERROR = Error while prompting for username and password.
 LAUNCHER_MALFORMED_URL = Unsupported storage URL: {0}
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/BuiltInCommandInfoTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/BuiltInCommandInfoTest.java	Thu May 02 10:58:20 2013 -0600
@@ -208,7 +208,7 @@
         assertFalse(options.getOption(CommonOptions.DB_URL_ARG).isRequired());
         Option dbUrlOption = options.getOption(CommonOptions.DB_URL_ARG);
         Translate<LocaleResources> t = LocaleResources.createLocalizer();
-        assertEquals(t.localize(LocaleResources.OPTION_DB_URL_DESC), dbUrlOption.getDescription());
+        assertEquals(t.localize(LocaleResources.OPTION_DB_URL_DESC).getContents(), dbUrlOption.getDescription());
         assertEquals("d", dbUrlOption.getOpt());
         assertEquals("dbUrl", dbUrlOption.getLongOpt());
     }
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/LauncherImplTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/LauncherImplTest.java	Thu May 02 10:58:20 2013 -0600
@@ -74,6 +74,7 @@
 import com.redhat.thermostat.common.cli.CommandException;
 import com.redhat.thermostat.common.cli.CommandRegistry;
 import com.redhat.thermostat.common.config.ClientPreferences;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.tools.ApplicationState;
 import com.redhat.thermostat.launcher.BundleManager;
 import com.redhat.thermostat.launcher.internal.DisallowSystemExitSecurityManager.ExitException;
@@ -341,7 +342,7 @@
 
     @Test
     public void testBadOption() {
-        String expected = "Unrecognized option: --argNotAccepted\n"
+        String expected = "Could not parse options: Unrecognized option: --argNotAccepted\n"
                 + "usage: thermostat test1 <--arg1 <arg>> [--arg2 <arg>]\n"
                 + "                  description 1\n"
                 + "thermostat test1\n"
@@ -365,7 +366,7 @@
 
     @Test
     public void testOptionMissingRequiredArgument() {
-        String expected = "Missing argument for option: arg1\n"
+        String expected = "Could not parse options: Missing argument for option: arg1\n"
                 + "usage: thermostat test1 <--arg1 <arg>> [--arg2 <arg>]\n"
                 + "                  description 1\n"
                 + "thermostat test1\n"
@@ -395,7 +396,7 @@
 
             @Override
             public void run(CommandContext ctx) throws CommandException {
-                throw new CommandException("test error");
+                throw new CommandException(new LocalizedString("test error"));
             }
 
         });
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/PluginConfigurationParserTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/PluginConfigurationParserTest.java	Thu May 02 10:58:20 2013 -0600
@@ -503,7 +503,7 @@
 
         assertEquals("dbUrl", dbUrlOption.getArgName());
         assertEquals(1, dbUrlOption.getArgs());
-        assertEquals(t.localize(LocaleResources.OPTION_DB_URL_DESC), dbUrlOption.getDescription());
+        assertEquals(t.localize(LocaleResources.OPTION_DB_URL_DESC).getContents(), dbUrlOption.getDescription());
         assertFalse(dbUrlOption.isRequired());
     }
 
--- a/numa/client-core/src/main/java/com/redhat/thermostat/numa/client/core/NumaView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/numa/client-core/src/main/java/com/redhat/thermostat/numa/client/core/NumaView.java	Thu May 02 10:58:20 2013 -0600
@@ -40,6 +40,7 @@
 
 import com.redhat.thermostat.client.core.views.BasicView;
 import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.storage.model.DiscreteTimeData;
 
 public abstract class NumaView extends BasicView implements UIComponent {
@@ -50,7 +51,7 @@
         public void hide(String tag);
     }
 
-    public abstract void addNumaChart(String tag, String humanReadableName);
+    public abstract void addNumaChart(String tag, LocalizedString name);
 
     public abstract void removeNumaChart(String tag);
 
--- a/numa/client-core/src/main/java/com/redhat/thermostat/numa/client/core/internal/NumaController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/numa/client-core/src/main/java/com/redhat/thermostat/numa/client/core/internal/NumaController.java	Thu May 02 10:58:20 2013 -0600
@@ -48,6 +48,7 @@
 import com.redhat.thermostat.common.ApplicationService;
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.Timer.SchedulingType;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.numa.client.core.NumaView;
 import com.redhat.thermostat.numa.client.core.NumaView.GraphVisibilityChangeListener;
@@ -164,7 +165,7 @@
     }
 
     @Override
-    public String getLocalizedName() {
+    public LocalizedString getLocalizedName() {
         return translator.localize(LocaleResources.NUMA_TAB);
     }
 }
--- a/numa/client-core/src/test/java/com/redhat/thermostat/numa/client/core/internal/NumaControllerTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/numa/client-core/src/test/java/com/redhat/thermostat/numa/client/core/internal/NumaControllerTest.java	Thu May 02 10:58:20 2013 -0600
@@ -42,6 +42,7 @@
 import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isA;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -64,6 +65,7 @@
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.Timer.SchedulingType;
 import com.redhat.thermostat.common.TimerFactory;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.numa.client.core.NumaView;
 import com.redhat.thermostat.numa.client.core.NumaView.GraphVisibilityChangeListener;
 import com.redhat.thermostat.numa.client.core.NumaViewProvider;
@@ -160,9 +162,9 @@
 
     @Test
     public void verifyNumCharts() {
-        verify(view).addNumaChart(eq("node0"), anyString());
-        verify(view).addNumaChart(eq("node1"), anyString());
-        verify(view).addNumaChart(eq("node2"), anyString());
+        verify(view).addNumaChart(eq("node0"), isA(LocalizedString.class));
+        verify(view).addNumaChart(eq("node1"), isA(LocalizedString.class));
+        verify(view).addNumaChart(eq("node2"), isA(LocalizedString.class));
     }
 
     @Test
@@ -229,7 +231,7 @@
         Locale defaultLocale = Locale.getDefault();
         try {
             Locale.setDefault(Locale.US);
-            assertEquals("NUMA", numaController.getLocalizedName());
+            assertEquals("NUMA", numaController.getLocalizedName().getContents());
         } finally {
             Locale.setDefault(defaultLocale);
         }
--- a/numa/client-swing/src/main/java/com/redhat/thermostat/numa/client/swing/internal/NumaPanel.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/numa/client-swing/src/main/java/com/redhat/thermostat/numa/client/swing/internal/NumaPanel.java	Thu May 02 10:58:20 2013 -0600
@@ -71,6 +71,7 @@
 import com.redhat.thermostat.client.ui.ChartColors;
 import com.redhat.thermostat.client.ui.RecentTimeSeriesChartController;
 import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.numa.client.core.NumaView;
 import com.redhat.thermostat.numa.client.locale.LocaleResources;
@@ -116,7 +117,7 @@
     }
 
     @Override
-    public void addNumaChart(final String tag, final String humanReadableName) {
+    public void addNumaChart(final String tag, final LocalizedString name) {
         SwingUtilities.invokeLater(new Runnable() {
             @Override
             public void run() {
@@ -124,7 +125,7 @@
                 colors.put(tag, ChartColors.getColor(colorIndex));
                 TimeSeries series = new TimeSeries(tag);
                 dataset.put(tag, series);
-                JCheckBox newCheckBox = new JCheckBox(createLabelWithLegend(humanReadableName, colors.get(tag)));
+                JCheckBox newCheckBox = new JCheckBox(createLabelWithLegend(name, colors.get(tag)));
                 newCheckBox.setActionCommand(tag);
                 newCheckBox.setSelected(true);
                 newCheckBox.addActionListener(numaCheckboxListener);
@@ -138,9 +139,9 @@
 
     }
 
-    private String createLabelWithLegend(String text, Color color) {
+    private String createLabelWithLegend(LocalizedString text, Color color) {
         String hexColor = "#" + Integer.toHexString(color.getRGB() & 0x00ffffff);
-        return "<html> <font color='" + hexColor + "'>\u2588</font> " + text + "</html>";
+        return "<html> <font color='" + hexColor + "'>\u2588</font> " + text.getContents() + "</html>";
     }
 
     @Override
@@ -276,8 +277,8 @@
     private JFreeChart createNumaChart() {
         JFreeChart chart = ChartFactory.createTimeSeriesChart(
                 null, // Title
-                translator.localize(LocaleResources.NUMA_CHART_TIME_LABEL), // x-axis Label
-                translator.localize(LocaleResources.NUMA_CHART_NUM_HITS_LABEL), // y-axis Label
+                translator.localize(LocaleResources.NUMA_CHART_TIME_LABEL).getContents(), // x-axis Label
+                translator.localize(LocaleResources.NUMA_CHART_NUM_HITS_LABEL).getContents(), // y-axis Label
                 numaCollection, // Dataset
                 false, // Show Legend
                 false, // Use tooltips
--- a/thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/collector/impl/ThreadMXBeanCollector.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/collector/impl/ThreadMXBeanCollector.java	Thu May 02 10:58:20 2013 -0600
@@ -46,7 +46,6 @@
 import org.osgi.framework.ServiceReference;
 
 import com.redhat.thermostat.client.command.RequestQueue;
-import com.redhat.thermostat.common.cli.CommandException;
 import com.redhat.thermostat.common.command.Request;
 import com.redhat.thermostat.common.command.Request.RequestType;
 import com.redhat.thermostat.common.command.RequestResponseListener;
@@ -126,7 +125,7 @@
         try {
             enqueueRequest(harvester);
             latch.await();
-        } catch (CommandException e) {
+        } catch (CommandChannelException e) {
             logger.log(Level.WARNING, "Failed to enqueue request", e);
         } catch (InterruptedException ignore) {}
         
@@ -160,7 +159,7 @@
         try {
             enqueueRequest(harvester);
             latch.await();
-        } catch (CommandException e) {
+        } catch (CommandChannelException e) {
             logger.log(Level.WARNING, "Failed to enqueue request", e);
         } catch (InterruptedException ignore) {}
         return result[0];
@@ -212,15 +211,23 @@
         return caps;
     }
     
-    private void enqueueRequest(Request req) throws CommandException {
+    private void enqueueRequest(Request req) throws CommandChannelException {
         ServiceReference ref = context.getServiceReference(RequestQueue.class.getName());
         if (ref == null) {
-            throw new CommandException("Cannot access command channel");
+            throw new CommandChannelException("Cannot access command channel");
         }
         RequestQueue queue = (RequestQueue) context.getService(ref);
         queue.putRequest(req);
         context.ungetService(ref);
     }
-    
+
+    @SuppressWarnings("serial")
+    private class CommandChannelException extends Exception {
+
+        public CommandChannelException(String message) {
+            super(message);
+        }
+
+    }
 }
 
--- a/thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/view/ThreadView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/view/ThreadView.java	Thu May 02 10:58:20 2013 -0600
@@ -41,8 +41,8 @@
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.common.ActionNotifier;
 import com.redhat.thermostat.common.ApplicationService;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.thread.client.common.ThreadTableBean;
-import com.redhat.thermostat.thread.client.common.chart.LivingDaemonThreadDifferenceChart;
 
 public abstract class ThreadView extends BasicView implements UIComponent {
 
@@ -75,7 +75,7 @@
     public abstract ThreadTimelineView createThreadTimelineView();
     public abstract ThreadCountView createThreadCountView();
     
-    public abstract void displayWarning(String warning);
+    public abstract void displayWarning(LocalizedString warning);
 
     public void setApplicationService(ApplicationService appService, String uniqueId) {
         this.appService = appService;
--- a/thread/client-controllers/pom.xml	Thu Apr 25 17:27:42 2013 -0600
+++ b/thread/client-controllers/pom.xml	Thu May 02 10:58:20 2013 -0600
@@ -66,6 +66,12 @@
       <artifactId>thermostat-common-core</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-test</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
 
     <dependency>
       <groupId>org.osgi</groupId>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/thread/client-controllers/src/main/java/com/redhat/thermostat/thread/client/controller/impl/LocaleResources.java	Thu May 02 10:58:20 2013 -0600
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2012, 2013 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.thread.client.controller.impl;
+
+import com.redhat.thermostat.common.locale.Translate;
+
+public enum LocaleResources {
+
+    CONTROLLER_NAME,
+
+    WARNING_CANNOT_DISABLE,
+    WARNING_CANNOT_ENABLE,
+    ;
+
+    static final String RESOURCE_BUNDLE = "com.redhat.thermostat.thread.client.controller.impl.strings";
+
+    public static Translate<LocaleResources> createLocalizer() {
+        return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class);
+    }
+
+}
--- a/thread/client-controllers/src/main/java/com/redhat/thermostat/thread/client/controller/impl/ThreadInformationController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/thread/client-controllers/src/main/java/com/redhat/thermostat/thread/client/controller/impl/ThreadInformationController.java	Thu May 02 10:58:20 2013 -0600
@@ -45,6 +45,8 @@
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.common.ApplicationService;
 import com.redhat.thermostat.common.TimerFactory;
+import com.redhat.thermostat.common.locale.LocalizedString;
+import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 import com.redhat.thermostat.storage.core.VmRef;
 import com.redhat.thermostat.storage.dao.VmInfoDAO;
@@ -60,6 +62,7 @@
 public class ThreadInformationController implements InformationServiceController<VmRef> {
 
     private static final Logger logger = LoggingUtils.getLogger(ThreadInformationController.class);
+    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
     
     private ThreadView view;
     private ThreadCollector collector;
@@ -93,8 +96,8 @@
     }
     
     @Override
-    public String getLocalizedName() {
-        return "Threads";
+    public LocalizedString getLocalizedName() {
+        return t.localize(LocaleResources.CONTROLLER_NAME);
     }
 
     @Override
@@ -113,7 +116,7 @@
             case START_LIVE_RECORDING:
                 result = collector.startHarvester();
                 if (!result) {
-                    view.displayWarning("Cannot enable Thread recording");
+                    view.displayWarning(t.localize(LocaleResources.WARNING_CANNOT_ENABLE));
                     view.setRecording(false, false);
                 }
                 break;
@@ -121,7 +124,7 @@
             case STOP_LIVE_RECORDING:
                 result = collector.stopHarvester();
                 if (!result) {
-                    view.displayWarning("Cannot disable Thread recording");
+                    view.displayWarning(t.localize(LocaleResources.WARNING_CANNOT_DISABLE));
                     view.setRecording(true, false);
                 }
                 break;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/thread/client-controllers/src/main/resources/com/redhat/thermostat/thread/client/controller/impl/strings.properties	Thu May 02 10:58:20 2013 -0600
@@ -0,0 +1,3 @@
+CONTROLLER_NAME = Threads
+WARNING_CANNOT_ENABLE = Cannot enable Thread recording
+WARNING_CANNOT_DISABLE = Cannot disable Thread recording
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/thread/client-controllers/src/test/java/com/redhat/thermostat/thread/client/controller/impl/LocaleResourcesTest.java	Thu May 02 10:58:20 2013 -0600
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2012, 2013 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.thread.client.controller.impl;
+
+import com.redhat.thermostat.testutils.AbstractLocaleResourcesTest;
+
+public class LocaleResourcesTest  extends AbstractLocaleResourcesTest<LocaleResources> {
+
+    @Override
+    protected Class<LocaleResources> getEnumClass() {
+        return LocaleResources.class;
+    }
+
+    @Override
+    protected String getResourceBundle() {
+        return LocaleResources.RESOURCE_BUNDLE;
+    }
+
+}
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadCountView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadCountView.java	Thu May 02 10:58:20 2013 -0600
@@ -37,8 +37,6 @@
 package com.redhat.thermostat.thread.client.swing.impl;
 
 import java.awt.Component;
-import java.awt.event.HierarchyEvent;
-import java.awt.event.HierarchyListener;
 
 import javax.swing.JPanel;
 import javax.swing.SwingUtilities;
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadDetailsView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadDetailsView.java	Thu May 02 10:58:20 2013 -0600
@@ -60,7 +60,7 @@
         details = new JPanel();
         details.setLayout(new BorderLayout(0, 0));
         
-        JLabel lblNewLabel = new JLabel(t.localize(LocaleResources.THREAD_DETAILS_EMTPY));
+        JLabel lblNewLabel = new JLabel(t.localize(LocaleResources.THREAD_DETAILS_EMTPY).getContents());
         lblNewLabel.setIcon(new ImageIcon(getEmptyDetailsIcon().getData().array()));
         details.add(lblNewLabel);
     }
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadTableView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadTableView.java	Thu May 02 10:58:20 2013 -0600
@@ -178,16 +178,16 @@
     private class ThreadViewTableModel extends DefaultTableModel {
 
         private String [] columns = {
-                t.localize(LocaleResources.NAME),
-                t.localize(LocaleResources.ID),
-                t.localize(LocaleResources.START),
-                t.localize(LocaleResources.STOP),
-                t.localize(LocaleResources.WAIT_COUNT),
-                t.localize(LocaleResources.BLOCK_COUNT),
-                t.localize(LocaleResources.RUNNING),
-                t.localize(LocaleResources.WAITING),
-                t.localize(LocaleResources.SLEEPING),
-                t.localize(LocaleResources.MONITOR), //, "Heap", "CPU Time", "User CPU Time"
+                t.localize(LocaleResources.NAME).getContents(),
+                t.localize(LocaleResources.ID).getContents(),
+                t.localize(LocaleResources.START).getContents(),
+                t.localize(LocaleResources.STOP).getContents(),
+                t.localize(LocaleResources.WAIT_COUNT).getContents(),
+                t.localize(LocaleResources.BLOCK_COUNT).getContents(),
+                t.localize(LocaleResources.RUNNING).getContents(),
+                t.localize(LocaleResources.WAITING).getContents(),
+                t.localize(LocaleResources.SLEEPING).getContents(),
+                t.localize(LocaleResources.MONITOR).getContents(), //, "Heap", "CPU Time", "User CPU Time"
         };
         
         private List<ThreadTableBean> infos;
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadView.java	Thu May 02 10:58:20 2013 -0600
@@ -43,7 +43,6 @@
 import java.beans.PropertyChangeListener;
 
 import javax.swing.JOptionPane;
-import javax.swing.JPanel;
 import javax.swing.JSplitPane;
 import javax.swing.JTabbedPane;
 import javax.swing.SwingUtilities;
@@ -51,11 +50,10 @@
 
 import com.redhat.thermostat.client.swing.ComponentVisibleListener;
 import com.redhat.thermostat.client.swing.SwingComponent;
-import com.redhat.thermostat.client.swing.components.ChartPanel;
 import com.redhat.thermostat.common.ApplicationService;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.thread.client.common.ThreadTableBean;
-import com.redhat.thermostat.thread.client.common.chart.LivingDaemonThreadDifferenceChart;
 import com.redhat.thermostat.thread.client.common.locale.LocaleResources;
 import com.redhat.thermostat.thread.client.common.view.ThreadCountView;
 import com.redhat.thermostat.thread.client.common.view.ThreadTableView;
@@ -111,8 +109,8 @@
             }
         });
         
-        panel.getToggleButton().setToolTipText(t.localize(LocaleResources.START_RECORDING));
-        panel.getToggleButton().setText(t.localize(LocaleResources.THREAD_MONITOR_SWITCH));
+        panel.getToggleButton().setToolTipText(t.localize(LocaleResources.START_RECORDING).getContents());
+        panel.getToggleButton().setText(t.localize(LocaleResources.THREAD_MONITOR_SWITCH).getContents());
         panel.getToggleButton().addItemListener(new ItemListener()
         {
             @Override
@@ -121,10 +119,10 @@
                 ThreadAction action = null;                
                 if (e.getStateChange() == ItemEvent.SELECTED) {
                     action = ThreadAction.START_LIVE_RECORDING;
-                    panel.getToggleButton().setToolTipText(t.localize(LocaleResources.STOP_RECORDING));
+                    panel.getToggleButton().setToolTipText(t.localize(LocaleResources.STOP_RECORDING).getContents());
                 } else {
                     action = ThreadAction.STOP_LIVE_RECORDING;
-                    panel.getToggleButton().setToolTipText(t.localize(LocaleResources.START_RECORDING));
+                    panel.getToggleButton().setToolTipText(t.localize(LocaleResources.START_RECORDING).getContents());
                 }
                 
                 if (skipNotification) return;
@@ -150,10 +148,10 @@
         topPane.setName("topTabbedPane");
         
         threadTimelineView = new SwingThreadTimelineView();
-        topPane.addTab(t.localize(LocaleResources.TIMELINE), threadTimelineView.getUiComponent());
+        topPane.addTab(t.localize(LocaleResources.TIMELINE).getContents(), threadTimelineView.getUiComponent());
         
         threadCountView = new SwingThreadCountView();
-        topPane.addTab(t.localize(LocaleResources.THREAD_COUNT), threadCountView.getUiComponent());
+        topPane.addTab(t.localize(LocaleResources.THREAD_COUNT).getContents(), threadCountView.getUiComponent());
         
         panel.getSplitPane().setTopComponent(topPane);
     }
@@ -163,14 +161,14 @@
         bottomPane.setName("bottomTabbedPane");
         
         threadTableView = new SwingThreadTableView();
-        bottomPane.addTab(t.localize(LocaleResources.TABLE), threadTableView.getUiComponent());
+        bottomPane.addTab(t.localize(LocaleResources.TABLE).getContents(), threadTableView.getUiComponent());
         
         threadDetailsView = new SwingThreadDetailsView();
-        bottomPane.addTab(t.localize(LocaleResources.DETAILS), threadDetailsView.getUiComponent());
+        bottomPane.addTab(t.localize(LocaleResources.DETAILS).getContents(), threadDetailsView.getUiComponent());
         threadDetailsPaneID = 1;
 
         vmCapsView = new SwingVMThreadCapabilitiesView();
-        bottomPane.addTab(t.localize(LocaleResources.VM_CAPABILITIES), vmCapsView.getUiComponent());
+        bottomPane.addTab(t.localize(LocaleResources.VM_CAPABILITIES).getContents(), vmCapsView.getUiComponent());
 
         panel.getSplitPane().setBottomComponent(bottomPane);
     }
@@ -219,11 +217,11 @@
     }
     
     @Override
-    public void displayWarning(final String warning) {
+    public void displayWarning(final LocalizedString warning) {
         SwingUtilities.invokeLater(new Runnable() {
             @Override
             public void run() {
-                JOptionPane.showMessageDialog(panel.getParent(), warning, "", JOptionPane.WARNING_MESSAGE);
+                JOptionPane.showMessageDialog(panel.getParent(), warning.getContents(), "", JOptionPane.WARNING_MESSAGE);
             }
         });
     }
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/ThreadAliveDaemonTimelinePanel.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/ThreadAliveDaemonTimelinePanel.java	Thu May 02 10:58:20 2013 -0600
@@ -82,9 +82,9 @@
                     .addComponent(timelinePanel, GroupLayout.DEFAULT_SIZE, 254, Short.MAX_VALUE))
         );
         
-        JLabel liveThreadsLabel = new JLabel(t.localize(LocaleResources.LIVE_THREADS) + ":");
+        JLabel liveThreadsLabel = new JLabel(t.localize(LocaleResources.LIVE_THREADS).getContents() + ":");
         
-        JLabel daemonThreadsLabel = new JLabel(t.localize(LocaleResources.DAEMON_THREADS) + ":");
+        JLabel daemonThreadsLabel = new JLabel(t.localize(LocaleResources.DAEMON_THREADS).getContents() + ":");
         
         liveThreads = new JLabel("-");
         liveThreads.setHorizontalAlignment(SwingConstants.RIGHT);
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/ThreadMainPanel.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/ThreadMainPanel.java	Thu May 02 10:58:20 2013 -0600
@@ -61,7 +61,7 @@
         setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
         
         HeaderPanel headerPanel = new HeaderPanel();
-        headerPanel.setHeader(t.localize(LocaleResources.THREAD_CONTROL_PANEL));
+        headerPanel.setHeader(t.localize(LocaleResources.THREAD_CONTROL_PANEL).getContents());
         
         JPanel content = new JPanel();
         headerPanel.setContent(content);
--- a/thread/client-swing/src/test/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadViewTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/thread/client-swing/src/test/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadViewTest.java	Thu May 02 10:58:20 2013 -0600
@@ -116,29 +116,29 @@
         });
         frameFixture = new FrameFixture(frame);
     }
-    
+
     @GUITest
     @Test
     public void verifyMonitorLabelChange() throws InvocationTargetException, InterruptedException {
         frameFixture.show();
-        
+
         JToggleButtonFixture togglefixture = frameFixture.toggleButton("recordButton");
         
-        togglefixture.requireToolTip(t.localize(LocaleResources.START_RECORDING));
-        
+        togglefixture.requireToolTip(t.localize(LocaleResources.START_RECORDING).getContents());
+
         togglefixture.click();
 
-        togglefixture.requireToolTip(t.localize(LocaleResources.STOP_RECORDING));
+        togglefixture.requireToolTip(t.localize(LocaleResources.STOP_RECORDING).getContents());
         
         // now try "programmatically"
         
         view.setRecording(true, true);
         
-        togglefixture.requireToolTip(t.localize(LocaleResources.STOP_RECORDING));
+        togglefixture.requireToolTip(t.localize(LocaleResources.STOP_RECORDING).getContents());
     
         view.setRecording(false, false);
         
-        togglefixture.requireToolTip(t.localize(LocaleResources.START_RECORDING));
+        togglefixture.requireToolTip(t.localize(LocaleResources.START_RECORDING).getContents());
     }
 
     @Category(GUITest.class)
--- a/vm-classstat/client-core/src/main/java/com/redhat/thermostat/vm/classstat/client/core/internal/VmClassStatController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-classstat/client-core/src/main/java/com/redhat/thermostat/vm/classstat/client/core/internal/VmClassStatController.java	Thu May 02 10:58:20 2013 -0600
@@ -49,6 +49,7 @@
 import com.redhat.thermostat.common.NotImplementedException;
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.Timer.SchedulingType;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.storage.core.VmRef;
 import com.redhat.thermostat.storage.model.DiscreteTimeData;
@@ -123,7 +124,7 @@
     }
 
     @Override
-    public String getLocalizedName() {
+    public LocalizedString getLocalizedName() {
         return translator.localize(LocaleResources.VM_INFO_TAB_CLASSES);
     }
 
--- a/vm-classstat/client-swing/src/main/java/com/redhat/thermostat/vm/classstat/client/swing/VmClassStatPanel.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-classstat/client-swing/src/main/java/com/redhat/thermostat/vm/classstat/client/swing/VmClassStatPanel.java	Thu May 02 10:58:20 2013 -0600
@@ -81,12 +81,12 @@
         // any name works
         dataset.addSeries(new TimeSeries("class-stat"));
 
-        visiblePanel.setHeader(t.localize(LocaleResources.VM_LOADED_CLASSES));
+        visiblePanel.setHeader(t.localize(LocaleResources.VM_LOADED_CLASSES).getContents());
 
         JFreeChart chart = ChartFactory.createTimeSeriesChart(
                 null,
-                t.localize(LocaleResources.VM_CLASSES_CHART_REAL_TIME_LABEL),
-                t.localize(LocaleResources.VM_CLASSES_CHART_LOADED_CLASSES_LABEL),
+                t.localize(LocaleResources.VM_CLASSES_CHART_REAL_TIME_LABEL).getContents(),
+                t.localize(LocaleResources.VM_CLASSES_CHART_LOADED_CLASSES_LABEL).getContents(),
                 dataset,
                 false, false, false);
 
--- a/vm-cpu/client-cli/src/main/java/com/redhat/thermostat/vm/cpu/client/cli/internal/VmCpuStatPrintDelegate.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-cpu/client-cli/src/main/java/com/redhat/thermostat/vm/cpu/client/cli/internal/VmCpuStatPrintDelegate.java	Thu May 02 10:58:20 2013 -0600
@@ -51,7 +51,7 @@
     
     private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
     
-    private static final String CPU_PERCENT = translator.localize(LocaleResources.COLUMN_HEADER_CPU_PERCENT);
+    private static final String CPU_PERCENT = translator.localize(LocaleResources.COLUMN_HEADER_CPU_PERCENT).getContents();
     
     private VmCpuStatDAO cpuStatDAO;
 
--- a/vm-cpu/client-core/src/main/java/com/redhat/thermostat/vm/cpu/client/core/internal/VmCpuController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-cpu/client-core/src/main/java/com/redhat/thermostat/vm/cpu/client/core/internal/VmCpuController.java	Thu May 02 10:58:20 2013 -0600
@@ -49,6 +49,7 @@
 import com.redhat.thermostat.common.NotImplementedException;
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.Timer.SchedulingType;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.storage.core.VmRef;
 import com.redhat.thermostat.storage.model.DiscreteTimeData;
@@ -130,7 +131,7 @@
     }
 
     @Override
-    public String getLocalizedName() {
+    public LocalizedString getLocalizedName() {
         return translator.localize(LocaleResources.VM_INFO_TAB_CPU);
     }
 }
--- a/vm-cpu/client-swing/src/main/java/com/redhat/thermostat/vm/cpu/client/swing/internal/VmCpuPanel.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-cpu/client-swing/src/main/java/com/redhat/thermostat/vm/cpu/client/swing/internal/VmCpuPanel.java	Thu May 02 10:58:20 2013 -0600
@@ -106,12 +106,12 @@
 
     private void initializePanel() {
         visiblePanel = new HeaderPanel();
-        visiblePanel.setHeader(translator.localize(LocaleResources.VM_CPU_TITLE));
+        visiblePanel.setHeader(translator.localize(LocaleResources.VM_CPU_TITLE).getContents());
 
         JFreeChart chart = ChartFactory.createTimeSeriesChart(
                 null,
-                translator.localize(LocaleResources.VM_CPU_CHART_TIME_LABEL),
-                translator.localize(LocaleResources.VM_CPU_CHART_LOAD_LABEL),
+                translator.localize(LocaleResources.VM_CPU_CHART_TIME_LABEL).getContents(),
+                translator.localize(LocaleResources.VM_CPU_CHART_LOAD_LABEL).getContents(),
                 data,
                 false, false, false);
 
--- a/vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/VmGcView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/VmGcView.java	Thu May 02 10:58:20 2013 -0600
@@ -40,11 +40,12 @@
 
 import com.redhat.thermostat.client.core.views.BasicView;
 import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.storage.model.IntervalTimeData;
 
 public abstract class VmGcView extends BasicView implements UIComponent {
 
-    public abstract void addChart(String tag, String title, String valueUnit);
+    public abstract void addChart(String tag, LocalizedString title, String valueUnit);
 
     public abstract void removeChart(String tag);
 
--- a/vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/internal/VmGcController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/internal/VmGcController.java	Thu May 02 10:58:20 2013 -0600
@@ -55,6 +55,7 @@
 import com.redhat.thermostat.common.NotImplementedException;
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.Timer.SchedulingType;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.storage.core.VmRef;
 import com.redhat.thermostat.storage.model.IntervalTimeData;
@@ -136,7 +137,7 @@
     }
 
     // FIXME
-    private String chartName(String collectorName, String generationName) {
+    private LocalizedString chartName(String collectorName, String generationName) {
         return translator.localize(LocaleResources.VM_GC_COLLECTOR_OVER_GENERATION,
                 collectorName, generationName);
     }
@@ -188,7 +189,7 @@
                 return g.getName();
             }
         }
-        return translator.localize(LocaleResources.UNKNOWN_GEN);
+        return translator.localize(LocaleResources.UNKNOWN_GEN).getContents();
     }
 
     public UIComponent getView() {
@@ -196,7 +197,7 @@
     }
 
     @Override
-    public String getLocalizedName() {
+    public LocalizedString getLocalizedName() {
         return translator.localize(LocaleResources.VM_INFO_TAB_GC);
     }
 
--- a/vm-gc/client-swing/src/main/java/com/redhat/thermostat/vm/gc/client/swing/internal/VmGcPanel.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-gc/client-swing/src/main/java/com/redhat/thermostat/vm/gc/client/swing/internal/VmGcPanel.java	Thu May 02 10:58:20 2013 -0600
@@ -70,6 +70,7 @@
 import com.redhat.thermostat.client.ui.RecentTimeSeriesChartController;
 import com.redhat.thermostat.client.ui.SampledDataset;
 import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.storage.model.IntervalTimeData;
 import com.redhat.thermostat.vm.gc.client.core.VmGcView;
@@ -128,11 +129,11 @@
 
     private void initializePanel() {
         visiblePanel.setContent(realPanel);
-        visiblePanel.setHeader(translator.localize(LocaleResources.VM_GC_TITLE));
+        visiblePanel.setHeader(translator.localize(LocaleResources.VM_GC_TITLE).getContents());
         realPanel.setLayout(new GridBagLayout());
     }
 
-    private JPanel createCollectorDetailsPanel(IntervalXYDataset collectorData, String title, String units) {
+    private JPanel createCollectorDetailsPanel(IntervalXYDataset collectorData, LocalizedString title, String units) {
         JPanel detailsPanel = new JPanel();
         detailsPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
         detailsPanel.setLayout(new BorderLayout());
@@ -141,8 +142,8 @@
 
         JFreeChart chart = ChartFactory.createHistogram(
             null,
-            translator.localize(LocaleResources.VM_GC_COLLECTOR_CHART_REAL_TIME_LABEL),
-            translator.localize(LocaleResources.VM_GC_COLLECTOR_CHART_GC_TIME_LABEL, units),
+            translator.localize(LocaleResources.VM_GC_COLLECTOR_CHART_REAL_TIME_LABEL).getContents(),
+            translator.localize(LocaleResources.VM_GC_COLLECTOR_CHART_GC_TIME_LABEL, units).getContents(),
             collectorData,
             PlotOrientation.VERTICAL,
             false,
@@ -194,7 +195,7 @@
     }
 
     @Override
-    public void addChart(final String tag, final String title, final String units) {
+    public void addChart(final String tag, final LocalizedString title, final String units) {
         SwingUtilities.invokeLater(new Runnable() {
             @Override
             public void run() {
--- a/vm-gc/remote-collector-client-swing/src/main/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButton.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-gc/remote-collector-client-swing/src/main/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButton.java	Thu May 02 10:58:20 2013 -0600
@@ -42,6 +42,7 @@
 import javax.swing.ImageIcon;
 
 import com.redhat.thermostat.client.swing.components.ActionButton;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 
 import com.redhat.thermostat.gc.remote.client.common.IconResources;
@@ -58,10 +59,10 @@
         this(action, translator.localize(LocaleResources.PERFORM_GC));
     }
     
-    private ToolbarGCButton(RequestGCAction action, String text) {
+    private ToolbarGCButton(RequestGCAction action, LocalizedString text) {
         super(new ImageIcon(IconResources.getGCIconSmall().getData().array()), text);
         
-        setToolTipText(text);
+        setToolTipText(text.getContents());
         this.action = action;
         
         addActionListener(new ToolbarGCButtonActionlistener());
--- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapDumpDetailsView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapDumpDetailsView.java	Thu May 02 10:58:20 2013 -0600
@@ -38,11 +38,12 @@
 
 import com.redhat.thermostat.client.core.views.BasicView;
 import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.common.locale.LocalizedString;
 
 public abstract class HeapDumpDetailsView extends BasicView implements UIComponent {
 
-    public abstract void addSubView(String title, HeapHistogramView child);
-    public abstract void addSubView(String title, ObjectDetailsView child);
-    public abstract void removeSubView(String title);
+    public abstract void addSubView(LocalizedString title, HeapHistogramView child);
+    public abstract void addSubView(LocalizedString title, ObjectDetailsView child);
+    public abstract void removeSubView(LocalizedString title);
 }
 
--- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapView.java	Thu May 02 10:58:20 2013 -0600
@@ -42,6 +42,7 @@
 import com.redhat.thermostat.client.core.views.UIComponent;
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.common.ActionNotifier;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.vm.heap.analysis.client.core.chart.OverviewChart;
 import com.redhat.thermostat.vm.heap.analysis.common.HeapDump;
 
@@ -87,7 +88,7 @@
     public abstract void setActiveDump(HeapDump dump);
     public abstract void notifyHeapDumpComplete();
 
-    public abstract void displayWarning(String string);
+    public abstract void displayWarning(LocalizedString string);
 
 }
 
--- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpController.java	Thu May 02 10:58:20 2013 -0600
@@ -52,6 +52,7 @@
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.Timer.SchedulingType;
 import com.redhat.thermostat.common.cli.CommandException;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.storage.core.VmRef;
 import com.redhat.thermostat.storage.dao.VmInfoDAO;
@@ -129,10 +130,10 @@
         
         model = new OverviewChart(
                     null,
-                    translator.localize(LocaleResources.HEAP_CHART_TIME_AXIS),
-                    translator.localize(LocaleResources.HEAP_CHART_HEAP_AXIS),
-                    translator.localize(LocaleResources.HEAP_CHART_CAPACITY),
-                    translator.localize(LocaleResources.HEAP_CHART_USED));
+                    translator.localize(LocaleResources.HEAP_CHART_TIME_AXIS).getContents(),
+                    translator.localize(LocaleResources.HEAP_CHART_HEAP_AXIS).getContents(),
+                    translator.localize(LocaleResources.HEAP_CHART_CAPACITY).getContents(),
+                    translator.localize(LocaleResources.HEAP_CHART_USED).getContents());
         
         timer = appService.getTimerFactory().createTimer();
         timer.setAction(new HeapOverviewDataCollector());
@@ -213,7 +214,7 @@
                     view.enableHeapDumping();
                     view.notifyHeapDumpComplete();
                 } catch (CommandException e) {
-                    view.displayWarning(e.getMessage());
+                    view.displayWarning(e.getTranslatedMessage());
                 }
             }
         });
@@ -248,7 +249,7 @@
     }
 
     @Override
-    public String getLocalizedName() {
+    public LocalizedString getLocalizedName() {
         return translator.localize(LocaleResources.HEAP_SECTION_TITLE);
     }
 
--- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpDetailsController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpDetailsController.java	Thu May 02 10:58:20 2013 -0600
@@ -42,6 +42,7 @@
 
 import com.redhat.thermostat.client.core.views.BasicView;
 import com.redhat.thermostat.common.ApplicationService;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpDetailsView;
@@ -81,7 +82,7 @@
         try {
             HeapHistogramView heapHistogramView = histogramViewProvider.createView();
             heapHistogramView.display(heapDump.getHistogram());
-            String title = translator.localize(LocaleResources.HEAP_DUMP_SECTION_HISTOGRAM);
+            LocalizedString title = translator.localize(LocaleResources.HEAP_DUMP_SECTION_HISTOGRAM);
             view.addSubView(title, heapHistogramView);
         } catch (IOException e) {
             log.log(Level.SEVERE, "unexpected error while reading heap dump", e);
--- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/ObjectRootsController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/ObjectRootsController.java	Thu May 02 10:58:20 2013 -0600
@@ -102,15 +102,31 @@
 
     private void showObjectDetails(HeapObjectUI uiObject) {
         JavaHeapObject obj = heapDump.findObject(uiObject.objectId);
-        String text = translator.localize(LocaleResources.COMMAND_OBJECT_INFO_OBJECT_ID) + " " + obj.getIdString() + "\n" +
-                translator.localize(LocaleResources.COMMAND_OBJECT_INFO_TYPE) + " " + obj.getClazz().getName() + "\n" +
-                translator.localize(LocaleResources.COMMAND_OBJECT_INFO_SIZE) + " " + String.valueOf(obj.getSize()) + " bytes" + "\n" +
-                translator.localize(LocaleResources.COMMAND_OBJECT_INFO_HEAP_ALLOCATED) + " " + String.valueOf(obj.isHeapAllocated()) + "\n";
+        String space = " ";
+        String newline = "\n";
+        StringBuilder builder = new StringBuilder();
+        builder.append(translator.localize(LocaleResources.COMMAND_OBJECT_INFO_OBJECT_ID).getContents())
+                .append(space)
+                .append(obj.getIdString())
+                .append(newline)
+                .append(translator.localize(LocaleResources.COMMAND_OBJECT_INFO_TYPE).getContents())
+                .append(space)
+                .append(obj.getClazz().getName())
+                .append(newline)
+                .append(translator.localize(LocaleResources.COMMAND_OBJECT_INFO_SIZE).getContents())
+                .append(space)
+                .append(String.valueOf(obj.getSize()))
+                .append(" bytes")
+                .append(newline)
+                .append(translator.localize(LocaleResources.COMMAND_OBJECT_INFO_HEAP_ALLOCATED).getContents())
+                .append(space)
+                .append(String.valueOf(obj.isHeapAllocated()))
+                .append(newline);
 
         if (obj.getRoot() != null) {
-            text = text + obj.getRoot().getDescription();
+            builder.append(obj.getRoot().getDescription());
         }
-        view.setObjectDetails(text);
+        view.setObjectDetails(builder.toString());
     }
 
 
--- a/vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpControllerTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpControllerTest.java	Thu May 02 10:58:20 2013 -0600
@@ -70,6 +70,7 @@
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.TimerFactory;
 import com.redhat.thermostat.common.cli.CommandException;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.storage.core.HostRef;
 import com.redhat.thermostat.storage.core.VmRef;
 import com.redhat.thermostat.storage.dao.VmInfoDAO;
@@ -344,7 +345,7 @@
     @Test
     public void testRequestHeapDumpFails() throws CommandException, InterruptedException {
         final CountDownLatch latch = new CountDownLatch(1);
-        final String errMessage = "Error dumping heap (agent: agent-id, vm: vm-id)";
+        final LocalizedString errMessage = new LocalizedString("Error dumping heap (agent: agent-id, vm: vm-id)");
         mockExecutorService(latch);
         setUpListeners();
         
--- a/vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpDetailsControllerTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpDetailsControllerTest.java	Thu May 02 10:58:20 2013 -0600
@@ -49,6 +49,7 @@
 import org.junit.Test;
 
 import com.redhat.thermostat.common.ApplicationService;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpDetailsView;
 import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpDetailsViewProvider;
 import com.redhat.thermostat.vm.heap.analysis.client.core.HeapHistogramView;
@@ -111,9 +112,9 @@
 
         verify(dump).searchObjects(isA(String.class), anyInt());
         verify(view)
-                .addSubView(isA(String.class), isA(HeapHistogramView.class));
+                .addSubView(isA(LocalizedString.class), isA(HeapHistogramView.class));
         verify(view)
-                .addSubView(isA(String.class), isA(ObjectDetailsView.class));
+                .addSubView(isA(LocalizedString.class), isA(ObjectDetailsView.class));
     }
 
 }
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapDetailsSwing.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapDetailsSwing.java	Thu May 02 10:58:20 2013 -0600
@@ -43,6 +43,7 @@
 import javax.swing.SwingUtilities;
 
 import com.redhat.thermostat.client.swing.SwingComponent;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpDetailsView;
 import com.redhat.thermostat.vm.heap.analysis.client.core.HeapHistogramView;
 import com.redhat.thermostat.vm.heap.analysis.client.core.ObjectDetailsView;
@@ -65,36 +66,36 @@
     }
 
     @Override
-    public void addSubView(final String title, final HeapHistogramView view) {
+    public void addSubView(final LocalizedString title, final HeapHistogramView view) {
         verifyIsSwingComponent(view);
         SwingUtilities.invokeLater(new Runnable() {
             @Override
             public void run() {
-                tabPane.insertTab(title, null, ((SwingComponent)view).getUiComponent(), null, 0);
+                tabPane.insertTab(title.getContents(), null, ((SwingComponent)view).getUiComponent(), null, 0);
             }
         });
     }
 
     @Override
-    public void addSubView(final String title, final ObjectDetailsView view) {
+    public void addSubView(final LocalizedString title, final ObjectDetailsView view) {
         verifyIsSwingComponent(view);
         SwingUtilities.invokeLater(new Runnable() {
             @Override
             public void run() {
-                tabPane.insertTab(title, null, ((SwingComponent)view).getUiComponent(), null, 1);
+                tabPane.insertTab(title.getContents(), null, ((SwingComponent)view).getUiComponent(), null, 1);
             }
         });
     }
 
     @Override
-    public void removeSubView(final String title) {
+    public void removeSubView(final LocalizedString title) {
         SwingUtilities.invokeLater(new Runnable() {
             @Override
             public void run() {
                 int tabCount = tabPane.getTabCount();
                 for (int i = 0; i < tabCount; i++) {
                     String tabTitle = tabPane.getTitleAt(i);
-                    if (tabTitle.equals(title)) {
+                    if (tabTitle.equals(title.getContents())) {
                         tabPane.removeTabAt(i);
                         return;
                     }
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapSwingView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapSwingView.java	Thu May 02 10:58:20 2013 -0600
@@ -59,6 +59,7 @@
 import com.redhat.thermostat.client.swing.ComponentVisibleListener;
 import com.redhat.thermostat.client.swing.SwingComponent;
 import com.redhat.thermostat.client.swing.components.HeaderPanel;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.vm.heap.analysis.client.core.HeapView;
 import com.redhat.thermostat.vm.heap.analysis.client.core.chart.OverviewChart;
@@ -100,7 +101,7 @@
         
         heapDetailPanel = new HeapPanel();
         
-        overview = new HeaderPanel(translator.localize(LocaleResources.HEAP_OVERVIEW_TITLE));
+        overview = new HeaderPanel(translator.localize(LocaleResources.HEAP_OVERVIEW_TITLE).getContents());
         overview.setContent(stats);
         overview.addHierarchyListener(new ViewVisibleListener());
 
@@ -273,8 +274,8 @@
     }
 
     @Override
-    public void displayWarning(String string) {
-        JOptionPane.showMessageDialog(visiblePane, string, "Warning", JOptionPane.WARNING_MESSAGE);
+    public void displayWarning(LocalizedString string) {
+        JOptionPane.showMessageDialog(visiblePane, string.getContents(), "Warning", JOptionPane.WARNING_MESSAGE);
     }
 }
 
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HistogramPanel.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HistogramPanel.java	Thu May 02 10:58:20 2013 -0600
@@ -70,7 +70,7 @@
         panel = new JPanel();
         panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
 
-        headerPanel = new HeaderPanel(translator.localize(LocaleResources.HEAP_DUMP_CLASS_USAGE));
+        headerPanel = new HeaderPanel(translator.localize(LocaleResources.HEAP_DUMP_CLASS_USAGE).getContents());
         panel.add(headerPanel);
     }
 
@@ -99,9 +99,9 @@
     private class HistogramTableModel extends DefaultTableModel {
 
         private final String[] columnNames = new String[] {
-            translator.localize(LocaleResources.HEAP_DUMP_HISTOGRAM_COLUMN_CLASS),
-            translator.localize(LocaleResources.HEAP_DUMP_HISTOGRAM_COLUMN_INSTANCES),
-            translator.localize(LocaleResources.HEAP_DUMP_HISTOGRAM_COLUMN_SIZE),
+            translator.localize(LocaleResources.HEAP_DUMP_HISTOGRAM_COLUMN_CLASS).getContents(),
+            translator.localize(LocaleResources.HEAP_DUMP_HISTOGRAM_COLUMN_INSTANCES).getContents(),
+            translator.localize(LocaleResources.HEAP_DUMP_HISTOGRAM_COLUMN_SIZE).getContents(),
         };
 
         private List<HistogramRecord> histogram;
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectDetailsPanel.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectDetailsPanel.java	Thu May 02 10:58:20 2013 -0600
@@ -122,19 +122,19 @@
 
         panel = new JPanel();
 
-        JLabel searchLabel = new JLabel(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_BROWSE_SEARCH_LABEL));
+        JLabel searchLabel = new JLabel(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_BROWSE_SEARCH_LABEL).getContents());
 
         searchField = new SearchField();
-        searchField.setTooltip(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_BROWSE_SEARCH_PATTERN_HELP));
+        searchField.setTooltip(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_BROWSE_SEARCH_PATTERN_HELP).getContents());
 
         JSplitPane splitPane = new JSplitPane();
         splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
         splitPane.setDividerLocation(0.8 /* 80% */);
 
-        toggleReferrersButton = new JToggleButton(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_BROWSE_REFERRERS));
+        toggleReferrersButton = new JToggleButton(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_BROWSE_REFERRERS).getContents());
         refGroup.add(toggleReferrersButton);
 
-        toggleReferencesButton = new JToggleButton(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_BROWSE_REFERENCES));
+        toggleReferencesButton = new JToggleButton(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_BROWSE_REFERENCES).getContents());
         refGroup.add(toggleReferencesButton);
 
         toggleReferrersButton.setSelected(true);
@@ -185,7 +185,7 @@
                 }
             }
         });
-        searchField.setLabel(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_BROWSE_SEARCH_HINT));
+        searchField.setLabel(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_BROWSE_SEARCH_HINT).getContents());
 
         java.awt.event.ActionListener treeToggleListener = new java.awt.event.ActionListener() {
             @Override
@@ -273,7 +273,7 @@
                     TreePath path = objectTree.getPathForRow(row);
                     final HeapObjectUI heapObject = (HeapObjectUI) ((LazyMutableTreeNode)path.getLastPathComponent()).getUserObject();
                     JPopupMenu popup = new JPopupMenu();
-                    JMenuItem findRootItem = new JMenuItem(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_FIND_ROOT));
+                    JMenuItem findRootItem = new JMenuItem(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_FIND_ROOT).getContents());
                     findRootItem.addActionListener(new java.awt.event.ActionListener() {
                         @Override
                         public void actionPerformed(java.awt.event.ActionEvent e) {
@@ -403,10 +403,10 @@
             @Override
             public void run() {
                 // TODO use some other gui control for this rather than a plain text box
-                String text = translator.localize(LocaleResources.COMMAND_OBJECT_INFO_OBJECT_ID) + obj.getIdString() + "\n" +
-                              translator.localize(LocaleResources.COMMAND_OBJECT_INFO_TYPE) + obj.getClazz().getName() + "\n" +
-                              translator.localize(LocaleResources.COMMAND_OBJECT_INFO_SIZE) + String.valueOf(obj.getSize()) + " bytes" + "\n" +
-                              translator.localize(LocaleResources.COMMAND_OBJECT_INFO_HEAP_ALLOCATED) + String.valueOf(obj.isHeapAllocated()) + "\n";
+                String text = translator.localize(LocaleResources.COMMAND_OBJECT_INFO_OBJECT_ID).getContents() + obj.getIdString() + "\n" +
+                              translator.localize(LocaleResources.COMMAND_OBJECT_INFO_TYPE).getContents() + obj.getClazz().getName() + "\n" +
+                              translator.localize(LocaleResources.COMMAND_OBJECT_INFO_SIZE).getContents() + String.valueOf(obj.getSize()) + " bytes" + "\n" +
+                              translator.localize(LocaleResources.COMMAND_OBJECT_INFO_HEAP_ALLOCATED).getContents() + String.valueOf(obj.isHeapAllocated()) + "\n";
                 objectDetailsPane.setText(text);
             }
         });
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectRootsFrame.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectRootsFrame.java	Thu May 02 10:58:20 2013 -0600
@@ -85,13 +85,13 @@
     private final JTextPane objectDetails;
 
     public ObjectRootsFrame() {
-        setTitle(translator.localize(LocaleResources.OBJECT_ROOTS_VIEW_TITLE));
+        setTitle(translator.localize(LocaleResources.OBJECT_ROOTS_VIEW_TITLE).getContents());
 
         dataModel = new DefaultTreeModel(ROOT);
         pathToRootTree = new JTree(dataModel);
         pathToRootTree.setName(TREE_NAME);
 
-        JLabel lblNewLabel = new JLabel(translator.localize(LocaleResources.OBJECT_ROOTS_VIEW_TITLE));
+        JLabel lblNewLabel = new JLabel(translator.localize(LocaleResources.OBJECT_ROOTS_VIEW_TITLE).getContents());
 
         JScrollPane scrollPane = new JScrollPane(pathToRootTree);
 
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/stats/HeapDumperPopup.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/stats/HeapDumperPopup.java	Thu May 02 10:58:20 2013 -0600
@@ -50,7 +50,7 @@
     private JMenuItem dumper;
     
     public HeapDumperPopup() {
-        dumper = new JMenuItem(translator.localize(LocaleResources.TRIGGER_HEAP_DUMP));
+        dumper = new JMenuItem(translator.localize(LocaleResources.TRIGGER_HEAP_DUMP).getContents());
         add(dumper);
     }
     
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/stats/StatsPanel.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/stats/StatsPanel.java	Thu May 02 10:58:20 2013 -0600
@@ -37,7 +37,6 @@
 package com.redhat.thermostat.vm.heap.analysis.client.swing.internal.stats;
 
 import java.awt.BorderLayout;
-import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
@@ -46,15 +45,11 @@
 
 import javax.swing.JPanel;
 
-import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.vm.heap.analysis.client.core.HeapView.DumpDisabledReason;
-import com.redhat.thermostat.vm.heap.analysis.client.locale.LocaleResources;
 import com.redhat.thermostat.vm.heap.analysis.common.HeapDump;
 
 @SuppressWarnings("serial")
 public class StatsPanel extends JPanel {
-    
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
 
     private HeapChartPanel heapPanel;
     private HeapDumperPopup popup;
@@ -72,7 +67,7 @@
         overlays = new ArrayList<>();
         
         popup = new HeapDumperPopup();
-        
+
         setLayout(new BorderLayout());
     }
     
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapDetailsSwingTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapDetailsSwingTest.java	Thu May 02 10:58:20 2013 -0600
@@ -61,6 +61,7 @@
 import org.junit.runner.RunWith;
 
 import com.redhat.thermostat.client.swing.EdtHelper;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.vm.heap.analysis.client.swing.internal.HeapDetailsSwing;
 import com.redhat.thermostat.vm.heap.analysis.client.swing.internal.HistogramPanel;
 import com.redhat.thermostat.vm.heap.analysis.client.swing.internal.ObjectDetailsPanel;
@@ -120,8 +121,8 @@
                 return new JPanel();
             }
         }));
-        view.addSubView("test1", histogramView);
-        view.addSubView("test2", objectDetailsView);
+        view.addSubView(new LocalizedString("test1"), histogramView);
+        view.addSubView(new LocalizedString("test2"), objectDetailsView);
 
         tabPane.requireTabTitles("test1", "test2");
     }
@@ -143,11 +144,11 @@
             }
         }));
 
-        view.addSubView("test1", histogramView);
+        view.addSubView(new LocalizedString("test1"), histogramView);
 
         tabPane.requireTabTitles("test1");
 
-        view.removeSubView("test1");
+        view.removeSubView(new LocalizedString("test1"));
 
         tabPane.requireTabTitles();
     }
--- a/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/DumpHeapCommand.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/DumpHeapCommand.java	Thu May 02 10:58:20 2013 -0600
@@ -77,7 +77,7 @@
         Runnable successHandler = new Runnable() {
             @Override
             public void run() {
-                ctx.getConsole().getOutput().println(translator.localize(LocaleResources.COMMAND_HEAP_DUMP_DONE));
+                ctx.getConsole().getOutput().println(translator.localize(LocaleResources.COMMAND_HEAP_DUMP_DONE).getContents());
                 s.release();
             }
         };
--- a/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/FindObjectsCommand.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/FindObjectsCommand.java	Thu May 02 10:58:20 2013 -0600
@@ -60,8 +60,8 @@
 
     private static final String HEAP_ID_ARG = "heapId";
     private static final String LIMIT_ARG = "limit";
-    private static final String HEADER_OBJECT_ID = translator.localize(LocaleResources.HEADER_OBJECT_ID);
-    private static final String HEADER_TYPE = translator.localize(LocaleResources.HEADER_OBJECT_TYPE);
+    private static final String HEADER_OBJECT_ID = translator.localize(LocaleResources.HEADER_OBJECT_ID).getContents();
+    private static final String HEADER_TYPE = translator.localize(LocaleResources.HEADER_OBJECT_TYPE).getContents();
     private static final int DEFAULT_LIMIT = 10;
 
     private BundleContext context;
@@ -102,12 +102,12 @@
 
         List<String> terms = ctx.getArguments().getNonOptionArguments();
         if (terms.size() == 0) {
-            ctx.getConsole().getOutput().println(translator.localize(LocaleResources.SEARCH_TERM_REQUIRED));
+            ctx.getConsole().getOutput().println(translator.localize(LocaleResources.SEARCH_TERM_REQUIRED).getContents());
             return;
         }
         String searchTerm = terms.get(0);
         if (searchTerm.trim().length() == 0) {
-            ctx.getConsole().getOutput().println(translator.localize(LocaleResources.SEARCH_TERM_REQUIRED));
+            ctx.getConsole().getOutput().println(translator.localize(LocaleResources.SEARCH_TERM_REQUIRED).getContents());
             return;
         }
 
--- a/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/FindRootCommand.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/FindRootCommand.java	Thu May 02 10:58:20 2013 -0600
@@ -98,7 +98,7 @@
         Collection<HeapPath<JavaHeapObject>> pathsToRoot = findRoot.findShortestPathsToRoot(obj, findAll);
         PrintStream out = ctx.getConsole().getOutput();
         if (pathsToRoot.isEmpty()) {
-            out.println(translator.localize(LocaleResources.COMMAND_FIND_ROOT_NO_ROOT_FOUND, PrintObjectUtils.objectToString(obj)));
+            out.println(translator.localize(LocaleResources.COMMAND_FIND_ROOT_NO_ROOT_FOUND, PrintObjectUtils.objectToString(obj)).getContents());
         } else {
             printPathsToRoot(snapshot, pathsToRoot, out);
         }
--- a/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ListHeapDumpsCommand.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ListHeapDumpsCommand.java	Thu May 02 10:58:20 2013 -0600
@@ -63,10 +63,10 @@
     private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
 
     private static final String[] COLUMN_NAMES = {
-        translator.localize(LocaleResources.HEADER_HOST_ID),
-        translator.localize(LocaleResources.HEADER_VM_ID),
-        translator.localize(LocaleResources.HEADER_HEAP_ID),
-        translator.localize(LocaleResources.HEADER_TIMESTAMP),
+        translator.localize(LocaleResources.HEADER_HOST_ID).getContents(),
+        translator.localize(LocaleResources.HEADER_VM_ID).getContents(),
+        translator.localize(LocaleResources.HEADER_HEAP_ID).getContents(),
+        translator.localize(LocaleResources.HEADER_TIMESTAMP).getContents(),
     };
 
     private final BundleContext context;
--- a/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ObjectInfoCommand.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ObjectInfoCommand.java	Thu May 02 10:58:20 2013 -0600
@@ -93,13 +93,13 @@
         snapshot = heapDump.getSnapshot();
         JavaHeapObject obj = objCmdHelper.getJavaHeapObject();
         TableRenderer table = new TableRenderer(2);
-        table.printLine(translator.localize(LocaleResources.COMMAND_OBJECT_INFO_OBJECT_ID), obj.getIdString());
-        table.printLine(translator.localize(LocaleResources.COMMAND_OBJECT_INFO_TYPE), obj.getClazz().getName());
-        table.printLine(translator.localize(LocaleResources.COMMAND_OBJECT_INFO_SIZE), String.valueOf(obj.getSize()) + " bytes");
-        table.printLine(translator.localize(LocaleResources.COMMAND_OBJECT_INFO_HEAP_ALLOCATED), String.valueOf(obj.isHeapAllocated()));
-        table.printLine(translator.localize(LocaleResources.COMMAND_OBJECT_INFO_REFERENCES), "");
+        table.printLine(translator.localize(LocaleResources.COMMAND_OBJECT_INFO_OBJECT_ID).getContents(), obj.getIdString());
+        table.printLine(translator.localize(LocaleResources.COMMAND_OBJECT_INFO_TYPE).getContents(), obj.getClazz().getName());
+        table.printLine(translator.localize(LocaleResources.COMMAND_OBJECT_INFO_SIZE).getContents(), String.valueOf(obj.getSize()) + " bytes");
+        table.printLine(translator.localize(LocaleResources.COMMAND_OBJECT_INFO_HEAP_ALLOCATED).getContents(), String.valueOf(obj.isHeapAllocated()));
+        table.printLine(translator.localize(LocaleResources.COMMAND_OBJECT_INFO_REFERENCES).getContents(), "");
         printReferences(table, obj);
-        table.printLine(translator.localize(LocaleResources.COMMAND_OBJECT_INFO_REFERRERS), "");
+        table.printLine(translator.localize(LocaleResources.COMMAND_OBJECT_INFO_REFERRERS).getContents(), "");
         printReferrers(table, obj);
 
         PrintStream out = ctx.getConsole().getOutput();
--- a/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/SaveHeapDumpToFileCommand.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/SaveHeapDumpToFileCommand.java	Thu May 02 10:58:20 2013 -0600
@@ -108,9 +108,9 @@
             if (heapStream != null) {
                 try {
                     saveHeapDump(heapStream, filename);
-                    ctx.getConsole().getOutput().println(translator.localize(LocaleResources.COMMAND_SAVE_HEAP_DUMP_SAVED_TO_FILE, filename));
+                    ctx.getConsole().getOutput().println(translator.localize(LocaleResources.COMMAND_SAVE_HEAP_DUMP_SAVED_TO_FILE, filename).getContents());
                 } catch (IOException e) {
-                    ctx.getConsole().getOutput().println(translator.localize(LocaleResources.COMMAND_SAVE_HEAP_DUMP_ERROR_SAVING, e.getMessage()));
+                    ctx.getConsole().getOutput().println(translator.localize(LocaleResources.COMMAND_SAVE_HEAP_DUMP_ERROR_SAVING, e.getMessage()).getContents());
                 }
             } else {
                 throw new HeapNotFoundException(heapId);
--- a/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ShowHeapHistogramCommand.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ShowHeapHistogramCommand.java	Thu May 02 10:58:20 2013 -0600
@@ -94,7 +94,7 @@
 
         ObjectHistogram histogram = heapDAO.getHistogram(heapInfo);
         if (histogram == null) {
-            ctx.getConsole().getOutput().println(translator.localize(LocaleResources.ERROR_READING_HISTOGRAM_MESSAGE, heapId));
+            ctx.getConsole().getOutput().println(translator.localize(LocaleResources.ERROR_READING_HISTOGRAM_MESSAGE, heapId).getContents());
             return;
         } else {
             printHeapHistogram(histogram, ctx.getConsole().getOutput());
--- a/vm-heap-analysis/command/src/test/java/com/redhat/thermostat/vm/heap/analysis/command/internal/DumpHeapCommandTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/command/src/test/java/com/redhat/thermostat/vm/heap/analysis/command/internal/DumpHeapCommandTest.java	Thu May 02 10:58:20 2013 -0600
@@ -144,7 +144,7 @@
             command.run(factory.createContext(args));
             assertTrue("should not reach here", false);
         } catch (CommandException ce) {
-            assertEquals(TRANSLATOR.localize(LocaleResources.AGENT_SERVICE_UNAVAILABLE), ce.getMessage());
+            assertEquals(TRANSLATOR.localize(LocaleResources.AGENT_SERVICE_UNAVAILABLE).getContents(), ce.getMessage());
         }
     }
     
@@ -167,7 +167,7 @@
             command.run(factory.createContext(args));
             fail();
         } catch (CommandException ce) {
-            assertEquals(TRANSLATOR.localize(LocaleResources.REQUEST_QUEUE_UNAVAILABLE), ce.getMessage());
+            assertEquals(TRANSLATOR.localize(LocaleResources.REQUEST_QUEUE_UNAVAILABLE).getContents(), ce.getMessage());
         }
     }
 
@@ -205,7 +205,7 @@
             fail("CommandException expected");
         } catch (CommandException e) {
             assertEquals(TRANSLATOR.localize(LocaleResources.HEAP_DUMP_ERROR,
-                    HOST_ID, String.valueOf(VM_ID)), e.getMessage());
+                    HOST_ID, String.valueOf(VM_ID)).getContents(), e.getMessage());
         }
     }
 
--- a/vm-heap-analysis/command/src/test/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ObjectInfoCommandTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/command/src/test/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ObjectInfoCommandTest.java	Thu May 02 10:58:20 2013 -0600
@@ -227,7 +227,7 @@
             cmd.run(factory.createContext(args));
             fail();
         } catch (CommandException e) {
-            assertEquals(translator.localize(LocaleResources.HEAP_SERVICE_UNAVAILABLE), e.getMessage());
+            assertEquals(translator.localize(LocaleResources.HEAP_SERVICE_UNAVAILABLE).getContents(), e.getMessage());
         }
     }
 }
--- a/vm-heap-analysis/command/src/test/java/com/redhat/thermostat/vm/heap/analysis/command/internal/SaveHeapDumpToFileCommandTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/command/src/test/java/com/redhat/thermostat/vm/heap/analysis/command/internal/SaveHeapDumpToFileCommandTest.java	Thu May 02 10:58:20 2013 -0600
@@ -150,7 +150,7 @@
             command.run(factory.createContext(args));
             fail();
         } catch (CommandException e) {
-            assertEquals(translator.localize(LocaleResources.HEAP_SERVICE_UNAVAILABLE), e.getMessage());
+            assertEquals(translator.localize(LocaleResources.HEAP_SERVICE_UNAVAILABLE).getContents(), e.getMessage());
         }
     }
 
--- a/vm-heap-analysis/command/src/test/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ShowHeapHistogramCommandTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-heap-analysis/command/src/test/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ShowHeapHistogramCommandTest.java	Thu May 02 10:58:20 2013 -0600
@@ -147,7 +147,7 @@
             command.run(factory.createContext(args));
             fail();
         } catch (CommandException e) {
-            assertEquals(translator.localize(LocaleResources.HEAP_SERVICE_UNAVAILABLE), e.getMessage());
+            assertEquals(translator.localize(LocaleResources.HEAP_SERVICE_UNAVAILABLE).getContents(), e.getMessage());
         }
     }
 }
--- a/vm-jmx/client-core/src/main/java/com/redhat/thermostat/vm/jmx/client/core/internal/JmxNotificationsViewController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-jmx/client-core/src/main/java/com/redhat/thermostat/vm/jmx/client/core/internal/JmxNotificationsViewController.java	Thu May 02 10:58:20 2013 -0600
@@ -49,6 +49,8 @@
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.TimerFactory;
+import com.redhat.thermostat.common.locale.LocalizedString;
+import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.storage.core.VmRef;
 import com.redhat.thermostat.storage.dao.AgentInfoDAO;
 import com.redhat.thermostat.vm.jmx.client.core.JmxNotificationsView;
@@ -65,6 +67,7 @@
     private final JmxNotificationDAO dao;
     private final AgentInfoDAO agentDAO;
     private final VmRef vm;
+    private final Translate<LocaleResources> t = LocaleResources.createLocalizer();
 
     private final AtomicBoolean notificationsEnabled = new AtomicBoolean(false);
 
@@ -149,8 +152,8 @@
     }
 
     @Override
-    public String getLocalizedName() {
-        return "Notifications";
+    public LocalizedString getLocalizedName() {
+        return t.localize(LocaleResources.NOTIFICATIONS);
     }
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-jmx/client-core/src/main/java/com/redhat/thermostat/vm/jmx/client/core/internal/LocaleResources.java	Thu May 02 10:58:20 2013 -0600
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2012, 2013 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.jmx.client.core.internal;
+
+import com.redhat.thermostat.common.locale.Translate;
+
+public enum LocaleResources {
+
+    NOTIFICATIONS,
+    ;
+
+    static final String RESOURCE_BUNDLE = "com.redhat.thermostat.vm.jmx.client.core.internal.strings";
+
+    public static Translate<LocaleResources> createLocalizer() {
+        return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-jmx/client-core/src/main/resources/com/redhat/thermostat/vm/jmx/client/core/internal/strings.properties	Thu May 02 10:58:20 2013 -0600
@@ -0,0 +1,1 @@
+NOTIFICATIONS = Notifications
--- a/vm-jmx/client-core/src/test/java/com/redhat/thermostat/vm/jmx/client/core/internal/JmxNotificationsViewControllerTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-jmx/client-core/src/test/java/com/redhat/thermostat/vm/jmx/client/core/internal/JmxNotificationsViewControllerTest.java	Thu May 02 10:58:20 2013 -0600
@@ -107,7 +107,7 @@
 
     @Test
     public void verifyGetLocalizedName() {
-        assertEquals("Notifications", controller.getLocalizedName());
+        assertEquals("Notifications", controller.getLocalizedName().getContents());
     }
 
     @Test
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-jmx/client-core/src/test/java/com/redhat/thermostat/vm/jmx/client/core/internal/LocaleResourcesTest.java	Thu May 02 10:58:20 2013 -0600
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2012, 2013 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.jmx.client.core.internal;
+
+import com.redhat.thermostat.testutils.AbstractLocaleResourcesTest;
+
+public class LocaleResourcesTest extends AbstractLocaleResourcesTest<LocaleResources> {
+
+    @Override
+    protected Class<LocaleResources> getEnumClass() {
+        return LocaleResources.class;
+    }
+
+    @Override
+    protected String getResourceBundle() {
+        return LocaleResources.RESOURCE_BUNDLE;
+    }
+
+}
--- a/vm-memory/client-cli/src/main/java/com/redhat/thermostat/vm/memory/client/cli/internal/VmMemoryStatPrintDelegate.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-memory/client-cli/src/main/java/com/redhat/thermostat/vm/memory/client/cli/internal/VmMemoryStatPrintDelegate.java	Thu May 02 10:58:20 2013 -0600
@@ -77,7 +77,7 @@
         VmMemoryStat memStat = (VmMemoryStat) stat;
         for (VmMemoryStat.Generation gen : memStat.getGenerations()) {
             for (VmMemoryStat.Space space : gen.getSpaces()) {
-                spacesNames.add(translator.localize(LocaleResources.COLUMN_HEADER_MEMORY_PATTERN, space.getName()));
+                spacesNames.add(translator.localize(LocaleResources.COLUMN_HEADER_MEMORY_PATTERN, space.getName()).getContents());
             }
         }
         return spacesNames;
--- a/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/MemoryStatsView.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/MemoryStatsView.java	Thu May 02 10:58:20 2013 -0600
@@ -39,6 +39,7 @@
 import com.redhat.thermostat.client.core.views.BasicView;
 import com.redhat.thermostat.client.core.views.UIComponent;
 import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.gc.remote.common.command.GCCommand;
 
 public abstract class MemoryStatsView extends BasicView implements UIComponent {
@@ -51,7 +52,7 @@
     
     public abstract void requestRepaint();
 
-    public abstract void displayWarning(String string);
+    public abstract void displayWarning(LocalizedString string);
 
 }
 
--- a/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/internal/MemoryStatsController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/core/internal/MemoryStatsController.java	Thu May 02 10:58:20 2013 -0600
@@ -56,6 +56,7 @@
 import com.redhat.thermostat.common.command.RequestResponseListener;
 import com.redhat.thermostat.common.command.Response;
 import com.redhat.thermostat.common.command.Response.ResponseType;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.gc.remote.common.GCRequest;
 import com.redhat.thermostat.gc.remote.common.command.GCCommand;
@@ -256,9 +257,8 @@
     }
 
     @Override
-    public String getLocalizedName() {
-        Translate<LocaleResources> t = LocaleResources.createLocalizer();
-        return t.localize(LocaleResources.VM_INFO_TAB_MEMORY);
+    public LocalizedString getLocalizedName() {
+        return translate.localize(LocaleResources.VM_INFO_TAB_MEMORY);
     }
 
     @Override
--- a/vm-memory/client-swing/src/main/java/com/redhat/thermostat/vm/memory/client/swing/internal/MemoryStatsViewImpl.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-memory/client-swing/src/main/java/com/redhat/thermostat/vm/memory/client/swing/internal/MemoryStatsViewImpl.java	Thu May 02 10:58:20 2013 -0600
@@ -53,6 +53,7 @@
 import com.redhat.thermostat.client.swing.SwingComponent;
 import com.redhat.thermostat.client.swing.components.HeaderPanel;
 import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.gc.remote.client.common.RequestGCAction;
 import com.redhat.thermostat.gc.remote.client.swing.ToolbarGCButton;
 import com.redhat.thermostat.gc.remote.common.command.GCCommand;
@@ -163,8 +164,8 @@
     }
 
     @Override
-    public void displayWarning(String string) {
-        JOptionPane.showMessageDialog(visiblePanel, string, "Warning", JOptionPane.WARNING_MESSAGE);
+    public void displayWarning(LocalizedString string) {
+        JOptionPane.showMessageDialog(visiblePanel, string.getContents(), "Warning", JOptionPane.WARNING_MESSAGE);
     }
 
     @Override
--- a/vm-overview/client-core/src/main/java/com/redhat/thermostat/vm/overview/client/core/internal/VmOverviewController.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-overview/client-core/src/main/java/com/redhat/thermostat/vm/overview/client/core/internal/VmOverviewController.java	Thu May 02 10:58:20 2013 -0600
@@ -49,6 +49,7 @@
 import com.redhat.thermostat.common.NotImplementedException;
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.Timer.SchedulingType;
+import com.redhat.thermostat.common.locale.LocalizedString;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.storage.core.VmRef;
 import com.redhat.thermostat.storage.dao.VmInfoDAO;
@@ -107,7 +108,7 @@
                     // Only show a stop time if we have actually stopped.
                     view.setVmStopTimeStamp(vmRunningTimeFormat.format(new Date(actualStopTime)));
                 } else {
-                    view.setVmStopTimeStamp(translator.localize(LocaleResources.VM_INFO_RUNNING));
+                    view.setVmStopTimeStamp(translator.localize(LocaleResources.VM_INFO_RUNNING).getContents());
                 }
                 view.setJavaVersion(info.getJavaVersion());
                 view.setJavaHome(info.getJavaHome());
@@ -117,7 +118,7 @@
                 String actualVmVersion = info.getVmVersion();
                 String actualVmInfo = info.getVmInfo();
                 view.setVmNameAndVersion(translator.localize(LocaleResources.VM_INFO_VM_NAME_AND_VERSION,
-                        actualVmName, actualVmVersion, actualVmInfo));
+                        actualVmName, actualVmVersion, actualVmInfo).getContents());
                 view.setVmArguments(info.getVmArguments());
             }
         });
@@ -140,7 +141,7 @@
     }
 
     @Override
-    public String getLocalizedName() {
+    public LocalizedString getLocalizedName() {
         return translator.localize(LocaleResources.VM_INFO_TAB_OVERVIEW);
     }
     
--- a/vm-overview/client-core/src/test/java/com/redhat/thermostat/vm/overview/client/core/internal/VmOverviewControllerTest.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-overview/client-core/src/test/java/com/redhat/thermostat/vm/overview/client/core/internal/VmOverviewControllerTest.java	Thu May 02 10:58:20 2013 -0600
@@ -147,7 +147,7 @@
         verify(view).setJavaCommandLine(eq(COMMAND_LINE));
         
         verify(view).setVmNameAndVersion(eq(translator.localize(LocaleResources.VM_INFO_VM_NAME_AND_VERSION,
-                        VM_NAME, VM_VERSION, VM_INFO)));
+                        VM_NAME, VM_VERSION, VM_INFO).getContents()));
         verify(view).setVmArguments(eq(VM_ARGS));
     }
 
--- a/vm-overview/client-swing/src/main/java/com/redhat/thermostat/vm/overview/client/swing/internal/VmOverviewPanel.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/vm-overview/client-swing/src/main/java/com/redhat/thermostat/vm/overview/client/swing/internal/VmOverviewPanel.java	Thu May 02 10:58:20 2013 -0600
@@ -199,7 +199,7 @@
     private void initializePanel() {
         visiblePanel = new HeaderPanel();
 
-        visiblePanel.setHeader(translator.localize(LocaleResources.VM_INFO_TITLE));
+        visiblePanel.setHeader(translator.localize(LocaleResources.VM_INFO_TITLE).getContents());
 
         SectionHeader processSection = new SectionHeader(translator.localize(LocaleResources.VM_INFO_SECTION_PROCESS));
         LabelField pidLabel = new LabelField(translator.localize(LocaleResources.VM_INFO_PROCESS_ID));
--- a/web/cmd/pom.xml	Thu Apr 25 17:27:42 2013 -0600
+++ b/web/cmd/pom.xml	Thu May 02 10:58:20 2013 -0600
@@ -84,6 +84,12 @@
       <artifactId>thermostat-common-core</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-test</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
 
     <dependency>
       <groupId>org.osgi</groupId>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/cmd/src/main/java/com/redhat/thermostat/web/cmd/LocaleResources.java	Thu May 02 10:58:20 2013 -0600
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2012, 2013 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.web.cmd;
+
+import com.redhat.thermostat.common.locale.Translate;
+
+public enum LocaleResources {
+
+    NEED_URL,
+    NEED_IP,
+    INVALID_PORT,
+    ;
+
+    static final String RESOURCE_BUNDLE = "com.redhat.thermostat.web.cmd.strings";
+
+    public static Translate<LocaleResources> createLocalizer() {
+        return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class);
+    }
+
+}
--- a/web/cmd/src/main/java/com/redhat/thermostat/web/cmd/WebServiceLauncher.java	Thu Apr 25 17:27:42 2013 -0600
+++ b/web/cmd/src/main/java/com/redhat/thermostat/web/cmd/WebServiceLauncher.java	Thu May 02 10:58:20 2013 -0600
@@ -50,6 +50,7 @@
 import org.eclipse.jetty.webapp.WebAppContext;
 
 import com.redhat.thermostat.common.config.InvalidConfigurationException;
+import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.common.utils.HostPortPair;
 import com.redhat.thermostat.storage.mongodb.MongoStorageProvider;
 import com.redhat.thermostat.web.server.WebStorageEndPoint;
@@ -60,6 +61,7 @@
 
 class WebServiceLauncher {
 
+    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
     private Server server;
     private String storageURL;
     private String storageUsername;
@@ -156,14 +158,14 @@
      */
     private void checkConfig() throws InvalidConfigurationException {
         if (storageURL == null) {
-            throw new InvalidConfigurationException("Storage URL must be set");
+            throw new InvalidConfigurationException(t.localize(LocaleResources.NEED_URL));
         }
         if (ipsPorts == null) {
-            throw new InvalidConfigurationException("IP adresses to bind to must be set");
+            throw new InvalidConfigurationException(t.localize(LocaleResources.NEED_IP));
         }
         for (HostPortPair pair: ipsPorts) {
             if (pair.getPort() <= 0) {
-                throw new InvalidConfigurationException("Invalid port number " + pair.getPort());
+                throw new InvalidConfigurationException(t.localize(LocaleResources.INVALID_PORT, Integer.toString(pair.getPort())));
             }
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/cmd/src/main/resources/com/redhat/thermostat/web/cmd/strings.properties	Thu May 02 10:58:20 2013 -0600
@@ -0,0 +1,3 @@
+NEED_URL = Storage URL must be set
+NEED_IP = IP adresses to bind to must be set
+INVALID_PORT = Invalid port number {0}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/cmd/src/test/java/com/redhat/thermostat/web/cmd/LocaleResourcesTest.java	Thu May 02 10:58:20 2013 -0600
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2012, 2013 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.web.cmd;
+
+import com.redhat.thermostat.testutils.AbstractLocaleResourcesTest;
+
+public class LocaleResourcesTest  extends AbstractLocaleResourcesTest<LocaleResources> {
+
+    @Override
+    protected Class<LocaleResources> getEnumClass() {
+        return LocaleResources.class;
+    }
+
+    @Override
+    protected String getResourceBundle() {
+        return LocaleResources.RESOURCE_BUNDLE;
+    }
+
+}
\ No newline at end of file