Refactor Blaze command line construction to allow for greater flexibility and separation of concerns.

--
MOS_MIGRATED_REVID=122067150
diff --git a/src/main/cpp/blaze.cc b/src/main/cpp/blaze.cc
index f30b307..72771a6 100644
--- a/src/main/cpp/blaze.cc
+++ b/src/main/cpp/blaze.cc
@@ -99,6 +99,7 @@
 static void WriteFileToStreamOrDie(FILE *stream, const char *file_name);
 static string BuildServerRequest();
 static int GetServerPid(const string &server_dir);
+static void VerifyJavaVersionAndSetJvm();
 
 // The following is a treatise on how the interaction between the client and the
 // server works.
@@ -409,6 +410,9 @@
   string product = globals->options.GetProductName();
   blaze_util::ToLower(&product);
   result.push_back(product + "(" + workspace + ")");
+  globals->options.AddJVMArgumentPrefix(
+      blaze_util::Dirname(blaze_util::Dirname(globals->jvm_path)),
+      &result);
   if (globals->options.batch) {
     result.push_back("-client");
     result.push_back("-Xms256m");
@@ -476,10 +480,11 @@
   }
   result.insert(result.end(), user_options.begin(), user_options.end());
 
-  result.push_back("-jar");
-  result.push_back(blaze::ConvertPath(
-      blaze_util::JoinPath(real_install_dir, globals->extracted_binaries[0])));
+  globals->options.AddJVMArgumentSuffix(real_install_dir,
+                                        globals->extracted_binaries[0],
+                                        &result);
 
+  // JVM arguments are complete. Now pass in Blaze startup flags.
   if (!globals->options.batch) {
     result.push_back("--max_idle_secs");
     result.push_back(ToString(globals->options.max_idle_secs));
@@ -606,7 +611,7 @@
 
 // Check the java version if a java version specification is bundled. On
 // success, returns the executable path of the java command.
-static string VerifyJavaVersionAndGetJvm() {
+static void VerifyJavaVersionAndSetJvm() {
   string exe = globals->options.GetJvm();
 
   string version_spec_file = blaze_util::JoinPath(
@@ -631,7 +636,7 @@
     }
   }
 
-  return exe;
+  globals->jvm_path = exe;
 }
 
 // Starts the Blaze server.  Returns a readable fd connected to the server.
@@ -652,9 +657,8 @@
     globals->restart_reason = NO_DAEMON;
   }
 
-  // Computing this path may report a fatal error, so do it before forking.
-  string exe = VerifyJavaVersionAndGetJvm();
-
+  string exe = globals->options.GetExe(globals->jvm_path,
+                                       globals->extracted_binaries[0]);
   // Go to the workspace before we daemonize, so
   // we can still print errors to the terminal.
   GoToWorkspace();
@@ -707,7 +711,8 @@
 
   GoToWorkspace();
 
-  string exe = VerifyJavaVersionAndGetJvm();
+  string exe = globals->options.GetExe(globals->jvm_path,
+                                       globals->extracted_binaries[0]);
   ExecuteProgram(exe, jvm_args_vector);
   pdie(blaze_exit_code::INTERNAL_ERROR, "execv of '%s' failed", exe.c_str());
 }
@@ -1861,6 +1866,7 @@
   ExtractData(self_path);
   blaze_server->Connect();
   EnsureCorrectRunningVersion(blaze_server);
+  VerifyJavaVersionAndSetJvm();
   KillRunningServerIfDifferentStartupOptions(blaze_server);
 
   if (globals->options.batch) {
diff --git a/src/main/cpp/blaze_globals.h b/src/main/cpp/blaze_globals.h
index fdadea1..4b80b49 100644
--- a/src/main/cpp/blaze_globals.h
+++ b/src/main/cpp/blaze_globals.h
@@ -55,6 +55,9 @@
   // the argument list passed on to the server.
   OptionProcessor option_processor;
 
+  // The path of the JVM executable that should be used to launch Blaze.
+  string jvm_path;
+
   pid_t server_pid;
 
   volatile sig_atomic_t sigint_count;
diff --git a/src/main/cpp/blaze_startup_options.cc b/src/main/cpp/blaze_startup_options.cc
index a7111e8..151232a 100644
--- a/src/main/cpp/blaze_startup_options.cc
+++ b/src/main/cpp/blaze_startup_options.cc
@@ -142,6 +142,22 @@
   exit(1);
 }
 
+string BlazeStartupOptions::GetExe(const string &jvm, const string &jar_path) {
+  return jvm;
+}
+
+void BlazeStartupOptions::AddJVMArgumentPrefix(const string &javabase,
+    std::vector<string> *result) const {
+}
+
+void BlazeStartupOptions::AddJVMArgumentSuffix(const string &real_install_dir,
+                                               const string &jar_path,
+    std::vector<string> *result) const {
+  result->push_back("-jar");
+  result->push_back(blaze::ConvertPath(
+      blaze_util::JoinPath(real_install_dir, jar_path)));
+}
+
 blaze_exit_code::ExitCode BlazeStartupOptions::AddJVMArguments(
     const string &host_javabase, vector<string> *result,
     const vector<string> &user_options, string *error) const {
diff --git a/src/main/cpp/blaze_startup_options.h b/src/main/cpp/blaze_startup_options.h
index 7ffaa83..d5ab0af 100644
--- a/src/main/cpp/blaze_startup_options.h
+++ b/src/main/cpp/blaze_startup_options.h
@@ -93,6 +93,20 @@
   // the startup options.
   string GetJvm();
 
+  // Returns the executable used to start the Blaze server, typically the given
+  // JVM.
+  string GetExe(const string &jvm, const string &jar_path);
+
+  // Adds JVM prefix flags to be set. These will be added before all other
+  // JVM flags.
+  void AddJVMArgumentPrefix(const string &javabase,
+    std::vector<string> *result) const;
+
+  // Adds JVM suffix flags. These will be added after all other JVM flags, and
+  // just before the Blaze server startup flags.
+  void AddJVMArgumentSuffix(const string &real_install_dir,
+    const string &jar_path, std::vector<string> *result) const;
+
   // Adds JVM tuning flags for Blaze.
   //
   // Returns the exit code after this operation. "error" will be set to a