/// <summary>
        /// Loads environment variables from SDK
        /// If any commands are added or removed the handling needs to be duplicated in
        /// TargetPlatformManagerModule.cpp
        /// </summary>
        /// <param name="PlatformSDKRoot">absolute path to platform SDK</param>
        /// <param name="OutputLevel">The output level for diagnostic messages</param>
        /// <returns>true if succeeded</returns>
        protected bool SetupEnvironmentFromAutoSDK(string PlatformSDKRoot, SDKOutputLevel OutputLevel)
        {
            string EnvVarFile = Path.Combine(PlatformSDKRoot, SDKEnvironmentVarsFile);

            if (File.Exists(EnvVarFile))
            {
                using (StreamReader Reader = new StreamReader(EnvVarFile))
                {
                    List <string> PathAdds    = new List <string>();
                    List <string> PathRemoves = new List <string>();

                    List <string> EnvVarNames  = new List <string>();
                    List <string> EnvVarValues = new List <string>();

                    bool   bNeedsToWriteAutoSetupEnvVar = true;
                    String PlatformSetupEnvVar          = GetPlatformAutoSDKSetupEnvVar();
                    for (; ;)
                    {
                        string VariableString = Reader.ReadLine();
                        if (VariableString == null)
                        {
                            break;
                        }

                        string[] Parts = VariableString.Split('=');
                        if (Parts.Length != 2)
                        {
                            LogAutoSDK(OutputLevel, "Incorrect environment variable declaration:");
                            LogAutoSDK(OutputLevel, VariableString);
                            return(false);
                        }

                        if (String.Compare(Parts[0], "strippath", true) == 0)
                        {
                            PathRemoves.Add(Parts[1]);
                        }
                        else if (String.Compare(Parts[0], "addpath", true) == 0)
                        {
                            PathAdds.Add(Parts[1]);
                        }
                        else
                        {
                            if (String.Compare(Parts[0], PlatformSetupEnvVar) == 0)
                            {
                                bNeedsToWriteAutoSetupEnvVar = false;
                            }
                            // convenience for setup.bat writers.  Trim any accidental whitespace from var names/values.
                            EnvVarNames.Add(Parts[0].Trim());
                            EnvVarValues.Add(Parts[1].Trim());
                        }
                    }

                    // don't actually set anything until we successfully validate and read all values in.
                    // we don't want to set a few vars, return a failure, and then have a platform try to
                    // build against a manually installed SDK with half-set env vars.
                    for (int i = 0; i < EnvVarNames.Count; ++i)
                    {
                        string EnvVarName  = EnvVarNames[i];
                        string EnvVarValue = EnvVarValues[i];
                        if (OutputLevel >= SDKOutputLevel.Verbose)
                        {
                            LogAutoSDK(OutputLevel, "Setting variable '{0}' to '{1}'", EnvVarName, EnvVarValue);
                        }
                        Environment.SetEnvironmentVariable(EnvVarName, EnvVarValue);
                    }


                    // actually perform the PATH stripping / adding.
                    String   OrigPathVar   = Environment.GetEnvironmentVariable("PATH");
                    String   PathDelimiter = UEBuildPlatform.GetPathVarDelimiter();
                    String[] PathVars      = { };
                    if (!String.IsNullOrEmpty(OrigPathVar))
                    {
                        PathVars = OrigPathVar.Split(PathDelimiter.ToCharArray());
                    }
                    else
                    {
                        LogAutoSDK(OutputLevel, "Path environment variable is null during AutoSDK");
                    }

                    List <String> ModifiedPathVars = new List <string>();
                    ModifiedPathVars.AddRange(PathVars);

                    // perform removes first, in case they overlap with any adds.
                    foreach (String PathRemove in PathRemoves)
                    {
                        foreach (String PathVar in PathVars)
                        {
                            if (PathVar.IndexOf(PathRemove, StringComparison.OrdinalIgnoreCase) >= 0)
                            {
                                LogAutoSDK(OutputLevel, "Removing Path: '{0}'", PathVar);
                                ModifiedPathVars.Remove(PathVar);
                            }
                        }
                    }

                    // remove all the of ADDs so that if this function is executed multiple times, the paths will be guaranteed to be in the same order after each run.
                    // If we did not do this, a 'remove' that matched some, but not all, of our 'adds' would cause the order to change.
                    foreach (String PathAdd in PathAdds)
                    {
                        foreach (String PathVar in PathVars)
                        {
                            if (String.Compare(PathAdd, PathVar, true) == 0)
                            {
                                LogAutoSDK(OutputLevel, "Removing Path: '{0}'", PathVar);
                                ModifiedPathVars.Remove(PathVar);
                            }
                        }
                    }

                    // perform adds, but don't add duplicates
                    foreach (String PathAdd in PathAdds)
                    {
                        if (!ModifiedPathVars.Contains(PathAdd))
                        {
                            LogAutoSDK(OutputLevel, "Adding Path: '{0}'", PathAdd);
                            ModifiedPathVars.Add(PathAdd);
                        }
                    }

                    String ModifiedPath = String.Join(PathDelimiter, ModifiedPathVars);
                    Environment.SetEnvironmentVariable("PATH", ModifiedPath);

                    Reader.Close();

                    // write out env var command so any process using this commandfile will mark itself as having had autosdks set up.
                    // avoids child processes spuriously detecting manualsdks.
                    if (bNeedsToWriteAutoSetupEnvVar)
                    {
                        using (StreamWriter Writer = File.AppendText(EnvVarFile))
                        {
                            Writer.WriteLine("{0}=1", PlatformSetupEnvVar);
                        }
                        // set the var in the local environment in case this process spawns any others.
                        Environment.SetEnvironmentVariable(PlatformSetupEnvVar, "1");
                    }

                    // make sure we know that we've modified the local environment, invalidating manual installs for this run.
                    bLocalProcessSetupAutoSDK = true;

                    return(true);
                }
            }
            else
            {
                LogAutoSDK(OutputLevel, "Cannot set up environment for {1} because command file {1} does not exist.", PlatformSDKRoot, EnvVarFile);
            }

            return(false);
        }