//--------------------------------------------------------------------
        //
        // Program Entry Method
        //
        //---------------------------------------------------------------------
        #region Entry

        //
        // Process command-line arguments.
        // Compile and execute the project.
        // Returns 0 if successful.
        //
        static int Main(string[] argsIn)
        {
            Project.Parameters projectParams = null;
            Parameters         cspParams     = null;

            int returnCode = ProcessArgs(
                argsIn,
                out projectParams,
                out cspParams
                );

            if (returnCode != _rc_success)
            {
                if (returnCode == _rc_exitAndReturnSuccess)
                {
                    return(_rc_success);
                }
                else
                {
                    return(returnCode);
                }
            }

            int projectReturnValue = _rc_projectBuildFailed;

            try
            {
                Project project = Project.Build(projectParams);

                if (project != null)
                {
                    projectReturnValue = project.ExecuteMain(projectParams.MainClass, projectParams.ProjectArgs);
                }
                else
                {
                    // Do nothing. If the project didn't build, we expect "Project" to have
                    // emitted some useful error messages.
                }
            }
            catch (CspProjectException e)
            {
                if (cspParams.SuppressExceptions)
                {
                    WriteErrorLine(e.Message);

                    return(_rc_cspProjectException);
                }
                else
                {
                    throw;
                }
            }
            catch (Exception e)
            {
                if (cspParams.SuppressExceptions)
                {
                    WriteErrorLine(e.Message);
                    WriteErrorLine("(To debug, rerun under a debugger, with the -debugMode parameter.)");

                    return(_rc_projectThrewException);
                }
                else
                {
                    throw;
                }
            }

            if (cspParams.BreakBeforeExit)
            {
                // Final breakpoint just before csp.exe quits.
                //
                // This is useful for seeing the output in the console window.
                System.Diagnostics.Debugger.Break();
            }

            return(projectReturnValue);
        }
        //--------------------------------------------------------------------
        //
        // Private Methods
        //
        //---------------------------------------------------------------------
        #region Private Methods


        //+-----------------------------------------------------------------------------
        //
        //  Function: ProcessArgs
        //
        //  Synopsis: Processes the command-line arguments and returns a structured
        //            form in argsOut.
        //
        //  Return value: A return code; if not _rc_success, caller should quit.
        //                May return _rc_exitAndReturnSuccess, which caller needs
        //                to translate to _rc_success.
        //
        //------------------------------------------------------------------------------

        static private int ProcessArgs(
            string[] argsIn,
            out Project.Parameters projParamsOut,
            out Parameters cspParamsOut
            )
        {
            projParamsOut = new Project.Parameters();
            cspParamsOut  = new Parameters();


            // Convert argsIn to a list

            ArrayList rgsArgs = new ArrayList();

            foreach (string arg in argsIn)
            {
                rgsArgs.Add(arg);
            }

            ArrayList alSourceFiles          = new ArrayList();
            ArrayList alReferencedAssemblies = new ArrayList();
            bool      noBreakBeforeInvoke    = false;
            bool      debugMode = false;

            if (rgsArgs.Count > 0)
            {
                string prefix = GetStandardizedPrefix((string)rgsArgs[0]);

                if ((prefix == "-h") ||
                    (prefix == "-?"))
                {
                    _Usage();
                    return(_rc_exitAndReturnSuccess);
                }
            }

            //
            // Process the arguments (until we hit "--").
            //

            bool fHitProjectParams = false;

            int idxCurrentArg;

            for (idxCurrentArg = 0; idxCurrentArg < rgsArgs.Count; idxCurrentArg++)
            {
                string arg    = ((string)rgsArgs[idxCurrentArg]).Trim();
                string prefix = GetStandardizedPrefix(arg);

                switch (prefix)
                {
                // response file - a file which contains more arguments for us to parse.
                case "-rsp:":
                {
                    string responseFile = arg.Substring(5);

                    if (!File.Exists(responseFile))
                    {
                        WriteErrorLine(String.Format(
                                           "Response file '{0}' not found.", responseFile));
                        return(_rc_fileNotFound);
                    }

                    // Remove this argument - replace it with the new arguments.

                    rgsArgs.RemoveAt(idxCurrentArg);
                    GetArgsFromFile(responseFile, idxCurrentArg, ref rgsArgs);

                    // Make the next iteration use the same index.
                    idxCurrentArg--;

                    break;
                }

                // source file - a .cs file which we will parse and then
                // compile.
                case "-s:":
                {
                    string sourceFile = arg.Substring(3);
                    if (!File.Exists(sourceFile))
                    {
                        WriteErrorLine(String.Format(
                                           "Source file '{0}' not found.", sourceFile));
                        return(_rc_fileNotFound);
                    }
                    alSourceFiles.Add(sourceFile);
                    break;
                }

                case "-r:":
                {
                    alReferencedAssemblies.Add(arg.Substring(3));
                    break;
                }

                case "-clrdir:":
                {
                    projParamsOut.ClrDir = arg.Substring(8);
                    break;
                }

                case "-debugmode":
                {
                    debugMode = true;
                    continue;
                }

                case "-enablecsprime":
                {
                    projParamsOut.EnableCsPrime = true;
                    continue;
                }

                case "-nobreakpoint":
                {
                    noBreakBeforeInvoke = true;
                    continue;
                }

                case "-main:":
                {
                    if (projParamsOut.MainClass != null)
                    {
                        _Usage();
                        return(_rc_usageError);
                    }
                    projParamsOut.MainClass = arg.Substring(6);
                    continue;
                }

                case "--":
                {
                    idxCurrentArg++;
                    fHitProjectParams = true;
                    break;
                }

                default:
                {
                    _Usage();
                    WriteErrorLine(String.Format(
                                       "Unrecognized option: '{0}'", arg));
                    return(_rc_usageError);
                }
                }

                if (fHitProjectParams)
                {
                    break;
                }
            }

            if (debugMode)
            {
                if (!noBreakBeforeInvoke)
                {
                    projParamsOut.BreakBeforeInvoke = true;
                }
                cspParamsOut.SuppressExceptions = false;
                cspParamsOut.BreakBeforeExit    = true;

                // This will leave files in the %temp% directory.
                // But seems necessary to get symbols.
                projParamsOut.DebugModeHack = true;
            }

            if (alSourceFiles.Count == 0)
            {
                _Usage();
                return(_rc_usageError);
            }

            projParamsOut.SourceFiles          = (string[])alSourceFiles.ToArray(typeof(string));
            projParamsOut.ReferencedAssemblies = (string[])alReferencedAssemblies.ToArray(typeof(string));


            // Set projParamsOut.ProjectArgs, to the parameters after the "--".

            int idxProjectArgs = idxCurrentArg;
            int nProjectArgs   = rgsArgs.Count - idxProjectArgs;

            if (nProjectArgs < 0)
            {
                nProjectArgs = 0;
            }

            projParamsOut.ProjectArgs = new string[nProjectArgs];

            if (nProjectArgs > 0)
            {
                rgsArgs.CopyTo(idxProjectArgs, projParamsOut.ProjectArgs, 0, nProjectArgs);
            }

            return(_rc_success);
        }