Set the default value of PRODUCT_NAME to "Bazel" and add a test to guarantee
Bazel is using the right value.

--
MOS_MIGRATED_REVID=125764994
diff --git a/src/main/cpp/blaze.cc b/src/main/cpp/blaze.cc
index c706c37..b9d4e09 100644
--- a/src/main/cpp/blaze.cc
+++ b/src/main/cpp/blaze.cc
@@ -375,7 +375,7 @@
   if (extractor.get() == NULL) {
     die(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
         "\nFailed to open %s as a zip file: (%d) %s",
-        globals->options.GetProductName().c_str(), errno, strerror(errno));
+        globals->options.product_name.c_str(), errno, strerror(errno));
   }
   if (extractor->ProcessAll() < 0) {
     die(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
@@ -406,7 +406,7 @@
   // ~/src/build_root/WORKSPACE file) will appear in ps(1) as "blaze(src)".
   string workspace =
       blaze_util::Basename(blaze_util::Dirname(globals->workspace));
-  string product = globals->options.GetProductName();
+  string product = globals->options.product_name;
   blaze_util::ToLower(&product);
   result.push_back(product + "(" + workspace + ")");
   globals->options.AddJVMArgumentPrefix(
@@ -549,7 +549,7 @@
                      globals->options.invocation_policy);
   }
 
-  result.push_back("--product_name=" + globals->options.GetProductName());
+  result.push_back("--product_name=" + globals->options.product_name);
 
   globals->options.AddExtraOptions(&result);
 
@@ -683,22 +683,22 @@
 
   if (VerboseLogging()) {
     fprintf(stderr, "Starting %s in batch mode.\n",
-            globals->options.GetProductName().c_str());
+            globals->options.product_name.c_str());
   }
   string command = globals->option_processor.GetCommand();
   vector<string> command_arguments;
   globals->option_processor.GetCommandArguments(&command_arguments);
 
   if (!command_arguments.empty() && command == "shutdown") {
-    string product = globals->options.GetProductName();
+    string product = globals->options.product_name;
     blaze_util::ToLower(&product);
     fprintf(stderr,
             "WARNING: Running command \"shutdown\" in batch mode.  Batch mode "
             "is triggered\nwhen not running %s within a workspace. If you "
             "intend to shutdown an\nexisting %s server, run \"%s "
             "shutdown\" from the directory where\nit was started.\n",
-            globals->options.GetProductName().c_str(),
-            globals->options.GetProductName().c_str(), product.c_str());
+            globals->options.product_name.c_str(),
+            globals->options.product_name.c_str(), product.c_str());
   }
   vector<string> jvm_args_vector = GetArgumentArray();
   if (command != "") {
@@ -785,7 +785,7 @@
   // or a JVM crash. Print out the jvm.out file in case there's something
   // useful.
   fprintf(stderr, "Error: unexpected EOF from %s server.\n"
-          "Contents of '%s':\n", globals->options.GetProductName().c_str(),
+          "Contents of '%s':\n", globals->options.product_name.c_str(),
           globals->jvm_log_file.c_str());
   WriteFileToStreamOrDie(stderr, globals->jvm_log_file.c_str());
   return GetExitCodeForAbruptExit(*globals);
@@ -882,7 +882,7 @@
       // the socket (the read will usually block).
       fprintf(stderr,
               "INFO: Waiting for response from %s server (pid %d)...\n",
-              globals->options.GetProductName().c_str(), globals->server_pid);
+              globals->options.product_name.c_str(), globals->server_pid);
       break;
     } else {  // result < 0
       // Error.  For EINTR we try again, all other errors are fatal.
@@ -1091,7 +1091,7 @@
   close(server_socket_);
   server_socket_ = -1;
   fprintf(stderr, "Sending SIGTERM to previous %s server (pid=%d)... ",
-          globals->options.GetProductName().c_str(), globals->server_pid);
+          globals->options.product_name.c_str(), globals->server_pid);
   fflush(stderr);
   kill(globals->server_pid, SIGTERM);
   if (WaitForServerDeath(globals->server_pid, 10)) {
@@ -1103,7 +1103,7 @@
   // If the previous attempt did not suceeded, kill the whole group.
   fprintf(stderr,
           "Sending SIGKILL to previous %s server process group (pid=%d)... ",
-          globals->options.GetProductName().c_str(), globals->server_pid);
+          globals->options.product_name.c_str(), globals->server_pid);
   fflush(stderr);
   killpg(globals->server_pid, SIGKILL);
   if (WaitForServerDeath(globals->server_pid, 10)) {
@@ -1219,18 +1219,18 @@
   }
 
   fprintf(stderr, "Extracting %s installation...\n",
-          globals->options.GetProductName().c_str());
+          globals->options.product_name.c_str());
   std::unique_ptr<devtools_ijar::ZipExtractor> extractor(
       devtools_ijar::ZipExtractor::Create(argv0.c_str(), &processor));
   if (extractor.get() == NULL) {
     die(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
         "\nFailed to open %s as a zip file: (%d) %s",
-        globals->options.GetProductName().c_str(), errno, strerror(errno));
+        globals->options.product_name.c_str(), errno, strerror(errno));
   }
   if (extractor->ProcessAll() < 0) {
     die(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
         "\nFailed to extract %s as a zip file: %s",
-        globals->options.GetProductName().c_str(), extractor->GetError());
+        globals->options.product_name.c_str(), extractor->GetError());
   }
 
   const time_t TEN_YEARS_IN_SEC = 3600 * 24 * 365 * 10;
@@ -1403,7 +1403,7 @@
     fprintf(stderr,
             "WARNING: Running %s server needs to be killed, because the "
             "startup options are different.\n",
-            globals->options.GetProductName().c_str());
+            globals->options.product_name.c_str());
     server->KillRunningServer();
   }
 }
@@ -1470,7 +1470,7 @@
     case SIGINT:
       if (++globals->sigint_count >= 3)  {
         sigprintf("\n%s caught third interrupt signal; killed.\n\n",
-                  globals->options.GetProductName().c_str());
+                  globals->options.product_name.c_str());
         if (globals->server_pid != -1) {
           KillServerProcess(globals->server_pid, globals->options.output_base,
                             globals->options.install_base);
@@ -1478,12 +1478,12 @@
         _exit(1);
       }
       sigprintf("\n%s caught interrupt signal; shutting down.\n\n",
-                globals->options.GetProductName().c_str());
+                globals->options.product_name.c_str());
       blaze_server->Cancel();
       break;
     case SIGTERM:
       sigprintf("\n%s caught terminate signal; shutting down.\n\n",
-                globals->options.GetProductName().c_str());
+                globals->options.product_name.c_str());
       blaze_server->Cancel();
       break;
     case SIGPIPE:
@@ -1657,7 +1657,7 @@
         globals->options.output_user_root, globals->workspace);
 #else
     globals->options.output_base = GetHashedBaseDirForWindows(
-        blaze::GetOutputRoot(), globals->options.GetProductName(),
+        blaze::GetOutputRoot(), globals->options.product_name,
         blaze::GetUserName(), globals->workspace);
 #endif
   }
diff --git a/src/main/cpp/blaze_startup_options.cc b/src/main/cpp/blaze_startup_options.cc
index 151232a..5c06462 100644
--- a/src/main/cpp/blaze_startup_options.cc
+++ b/src/main/cpp/blaze_startup_options.cc
@@ -38,7 +38,8 @@
 }
 
 BlazeStartupOptions::BlazeStartupOptions(const BlazeStartupOptions &rhs)
-    : output_base(rhs.output_base),
+    : product_name(rhs.product_name),
+      output_base(rhs.output_base),
       install_base(rhs.install_base),
       output_root(rhs.output_root),
       output_user_root(rhs.output_user_root),
@@ -69,10 +70,6 @@
   return *this;
 }
 
-string BlazeStartupOptions::GetProductName() {
-  return "Bazel";
-}
-
 string BlazeStartupOptions::GetOutputRoot() {
   return blaze::GetOutputRoot();
 }
diff --git a/src/main/cpp/blaze_startup_options.h b/src/main/cpp/blaze_startup_options.h
index d5ab0af..68b98ac 100644
--- a/src/main/cpp/blaze_startup_options.h
+++ b/src/main/cpp/blaze_startup_options.h
@@ -44,9 +44,6 @@
   ~BlazeStartupOptions();
   BlazeStartupOptions& operator=(const BlazeStartupOptions &rhs);
 
-  // Returns the capitalized name of this binary.
-  string GetProductName();
-
   // Parses a single argument, either from the command line or from the .blazerc
   // "startup" options.
   //
@@ -115,6 +112,9 @@
     const string &host_javabase, std::vector<string> *result,
     const std::vector<string> &user_options, string *error) const;
 
+  // The capitalized name of this binary.
+  string product_name;
+
   // Blaze's output base.  Everything is relative to this.  See
   // the BlazeDirectories Java class for details.
   string output_base;
diff --git a/src/main/cpp/blaze_startup_options_common.cc b/src/main/cpp/blaze_startup_options_common.cc
index 4df4d66..f1b589cb 100644
--- a/src/main/cpp/blaze_startup_options_common.cc
+++ b/src/main/cpp/blaze_startup_options_common.cc
@@ -24,6 +24,10 @@
 #include "src/main/cpp/util/numbers.h"
 #include "src/main/cpp/util/strings.h"
 
+#ifndef PRODUCT_NAME
+#define PRODUCT_NAME "Bazel"
+#endif
+
 namespace blaze {
 
 void BlazeStartupOptions::Init() {
@@ -34,10 +38,11 @@
     output_root = GetOutputRoot();
   }
 
-  string product = GetProductName();
-  blaze_util::ToLower(&product);
+  product_name = PRODUCT_NAME;
+  string product_name_lower = PRODUCT_NAME;
+  blaze_util::ToLower(&product_name_lower);
   output_user_root = blaze_util::JoinPath(
-      output_root, "_" + product + "_" + GetUserName());
+      output_root, "_" + product_name_lower + "_" + GetUserName());
   deep_execroot = true;
   block_for_lock = true;
   host_jvm_debug = false;
@@ -67,6 +72,7 @@
     const BlazeStartupOptions &rhs, BlazeStartupOptions *lhs) {
   assert(lhs);
 
+  lhs->product_name = rhs.product_name;
   lhs->output_base = rhs.output_base;
   lhs->install_base = rhs.install_base;
   lhs->output_root = rhs.output_root;
@@ -265,7 +271,7 @@
           error,
           "Unknown %s startup option: '%s'.\n"
           "  For more info, run '%s help startup_options'.",
-          GetProductName().c_str(), arg, GetProductName().c_str());
+          product_name.c_str(), arg, product_name.c_str());
       return blaze_exit_code::BAD_ARGV;
     }
   }
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java
index e71e2d2..9f80d6a 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java
@@ -250,7 +250,7 @@
 
   @Option(name = "product_name",
       defaultValue = "bazel", // NOTE: purely decorative!
-      category = "undocumented",
+      category = "hidden",
       help = "The name of the build system. It is used as part of the name of the generated "
           + "directories (e.g. productName-bin for binaries) as well as for printing error "
           + "messages and logging")
diff --git a/src/test/shell/bazel/BUILD b/src/test/shell/bazel/BUILD
index d7d9950..40b34bc 100644
--- a/src/test/shell/bazel/BUILD
+++ b/src/test/shell/bazel/BUILD
@@ -338,6 +338,13 @@
     ],
 )
 
+sh_test(
+    name = "client_test",
+    size = "medium",
+    srcs = ["client_test.sh"],
+    data = [":test-deps"],
+)
+
 test_suite(
     name = "all_tests",
     visibility = ["//visibility:public"],
diff --git a/src/test/shell/bazel/client_test.sh b/src/test/shell/bazel/client_test.sh
new file mode 100755
index 0000000..8e72d39
--- /dev/null
+++ b/src/test/shell/bazel/client_test.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Copyright 2016 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Integration tests for Bazel client.
+#
+
+# Load test environment
+source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"/test-setup.sh \
+  || { echo "test-setup.sh not found!" >&2; exit 1; }
+
+function test_product_name_with_bazel_info() {
+    bazel info >& "$TEST_log" || fail "Expected zero exit"
+
+    expect_log "^bazel-bin:.*_bazel.*bazel-out.*bin\$"
+    expect_log "^bazel-genfiles:.*_bazel.*bazel-out.*genfiles\$"
+    expect_log "^bazel-testlogs:.*_bazel.*bazel-out.*testlogs\$"
+    expect_log "^output_path:.*_bazel.*bazel-out\$"
+}