Ejemplo n.º 1
0
        /// <summary>
        /// Sets the thead count to the number of processors if the current thread count is set to 0.
        /// </summary>
        /// <remarks>The thread count value must be greater than 0 otherwise and exception will be thrown.</remarks>
        private void SetCabbingThreadCount()
        {
            // default the number of cabbing threads to the number of processors if it wasn't specified
            if (0 == this.CabbingThreadCount)
            {
                string numberOfProcessors = System.Environment.GetEnvironmentVariable("NUMBER_OF_PROCESSORS");

                try
                {
                    if (null != numberOfProcessors)
                    {
                        this.CabbingThreadCount = Convert.ToInt32(numberOfProcessors, CultureInfo.InvariantCulture.NumberFormat);

                        if (0 >= this.CabbingThreadCount)
                        {
                            throw new WixException(ErrorMessages.IllegalEnvironmentVariable("NUMBER_OF_PROCESSORS", numberOfProcessors));
                        }
                    }
                    else // default to 1 if the environment variable is not set
                    {
                        this.CabbingThreadCount = 1;
                    }

                    this.Messaging.Write(VerboseMessages.SetCabbingThreadCount(this.CabbingThreadCount.ToString()));
                }
                catch (ArgumentException)
                {
                    throw new WixException(ErrorMessages.IllegalEnvironmentVariable("NUMBER_OF_PROCESSORS", numberOfProcessors));
                }
                catch (FormatException)
                {
                    throw new WixException(ErrorMessages.IllegalEnvironmentVariable("NUMBER_OF_PROCESSORS", numberOfProcessors));
                }
            }
        }
Ejemplo n.º 2
0
        private int CalculateCabbingThreadCount()
        {
            var cabbingThreadCount = 1;  // default to 1 if the environment variable is not set.

            var numberOfProcessors = Environment.GetEnvironmentVariable("NUMBER_OF_PROCESSORS");

            try
            {
                if (!String.IsNullOrEmpty(numberOfProcessors))
                {
                    cabbingThreadCount = Convert.ToInt32(numberOfProcessors, CultureInfo.InvariantCulture.NumberFormat);

                    if (cabbingThreadCount <= 0)
                    {
                        throw new WixException(ErrorMessages.IllegalEnvironmentVariable("NUMBER_OF_PROCESSORS", numberOfProcessors));
                    }
                }

                this.Messaging.Write(VerboseMessages.SetCabbingThreadCount(this.CabbingThreadCount.ToString()));
            }
            catch (ArgumentException)
            {
                throw new WixException(ErrorMessages.IllegalEnvironmentVariable("NUMBER_OF_PROCESSORS", numberOfProcessors));
            }
            catch (FormatException)
            {
                throw new WixException(ErrorMessages.IllegalEnvironmentVariable("NUMBER_OF_PROCESSORS", numberOfProcessors));
            }

            return(cabbingThreadCount);
        }
        public void Execute()
        {
            this.lastCabinetAddedToMediaTable = new Dictionary <string, string>();

            // If the cabbing thread count wasn't provided, default the number of cabbing threads to the number of processors.
            if (this.CabbingThreadCount <= 0)
            {
                this.CabbingThreadCount = this.CalculateCabbingThreadCount();

                this.Messaging.Write(VerboseMessages.SetCabbingThreadCount(this.CabbingThreadCount.ToString()));
            }

            // Send Binder object to Facilitate NewCabNamesCallBack Callback
            var cabinetBuilder = new CabinetBuilder(this.Messaging, this.CabbingThreadCount, Marshal.GetFunctionPointerForDelegate(this.newCabNamesCallBack));

            // Supply Compile MediaTemplate Attributes to Cabinet Builder
            this.GetMediaTemplateAttributes(out var maximumCabinetSizeForLargeFileSplitting, out var maximumUncompressedMediaSize);
            cabinetBuilder.MaximumCabinetSizeForLargeFileSplitting = maximumCabinetSizeForLargeFileSplitting;
            cabinetBuilder.MaximumUncompressedMediaSize            = maximumUncompressedMediaSize;

            foreach (var entry in this.FileFacadesByCabinet)
            {
                var mediaSymbol      = entry.Key;
                var files            = entry.Value;
                var compressionLevel = mediaSymbol.CompressionLevel ?? this.DefaultCompressionLevel ?? CompressionLevel.Medium;
                var cabinetDir       = this.ResolveMedia(mediaSymbol, mediaSymbol.Layout, this.LayoutDirectory);

                var cabinetWorkItem = this.CreateCabinetWorkItem(this.Data, cabinetDir, mediaSymbol, compressionLevel, files);
                if (null != cabinetWorkItem)
                {
                    cabinetBuilder.Enqueue(cabinetWorkItem);
                }
            }

            // stop processing if an error previously occurred
            if (this.Messaging.EncounteredError)
            {
                return;
            }

            // create queued cabinets with multiple threads
            cabinetBuilder.CreateQueuedCabinets();
            if (this.Messaging.EncounteredError)
            {
                return;
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Parse the commandline arguments.
        /// </summary>
        /// <param name="args">Commandline arguments.</param>
        public string[] Parse(string[] args)
        {
            List <string> unprocessed = new List <string>();

            for (int i = 0; i < args.Length; ++i)
            {
                string arg = args[i];
                if (String.IsNullOrEmpty(arg)) // skip blank arguments
                {
                    continue;
                }

                if (1 == arg.Length) // treat '-' and '@' as filenames when by themselves.
                {
                    unprocessed.Add(arg);
                }
                else if ('-' == arg[0] || '/' == arg[0])
                {
                    string parameter = arg.Substring(1);
                    if (parameter.Equals("b", StringComparison.Ordinal))
                    {
                        if (!CommandLineHelper.IsValidArg(args, ++i))
                        {
                            break;
                        }

                        var bindPath = BindPath.Parse(args[i]);

                        this.BindPaths.Add(bindPath);
                    }
                    else if (parameter.StartsWith("cultures:", StringComparison.Ordinal))
                    {
                        string culturesString = arg.Substring(10).ToLower(CultureInfo.InvariantCulture);

                        // When null is used treat it as if cultures wasn't specified.
                        // This is needed for batching over the light task when using MSBuild which doesn't
                        // support empty items
                        if (culturesString.Equals("null", StringComparison.OrdinalIgnoreCase))
                        {
                            this.Cultures = null;
                        }
                        else
                        {
                            this.Cultures = culturesString.Split(';', ',');

                            for (int c = 0; c < this.Cultures.Length; ++c)
                            {
                                // Neutral is different from null. For neutral we still want to do WXL filtering.
                                // Set the culture to the empty string = identifier for the invariant culture
                                if (this.Cultures[c].Equals("neutral", StringComparison.OrdinalIgnoreCase))
                                {
                                    this.Cultures[c] = String.Empty;
                                }
                            }
                        }
                    }
                    else if (parameter.StartsWith("dcl:", StringComparison.Ordinal))
                    {
                        string defaultCompressionLevel = arg.Substring(5);

                        if (String.IsNullOrEmpty(defaultCompressionLevel))
                        {
                            break;
                        }
                        else if (Enum.TryParse(defaultCompressionLevel, true, out CompressionLevel compressionLevel))
                        {
                            this.DefaultCompressionLevel = compressionLevel;
                        }
                    }
                    else if (parameter.StartsWith("d", StringComparison.Ordinal))
                    {
                        parameter = arg.Substring(2);
                        string[] value = parameter.Split("=".ToCharArray(), 2);

                        string preexisting;
                        if (1 == value.Length)
                        {
                            this.Messaging.Write(ErrorMessages.ExpectedWixVariableValue(value[0]));
                        }
                        else if (this.Variables.TryGetValue(value[0], out preexisting))
                        {
                            this.Messaging.Write(ErrorMessages.WixVariableCollision(null, value[0]));
                        }
                        else
                        {
                            this.Variables.Add(value[0], value[1]);
                        }
                    }
                    else if (parameter.Equals("ext", StringComparison.Ordinal))
                    {
                        if (!CommandLineHelper.IsValidArg(args, ++i))
                        {
                            this.Messaging.Write(ErrorMessages.TypeSpecificationForExtensionRequired("-ext"));
                            break;
                        }

                        this.Extensions.Add(args[i]);
                    }
                    else if (parameter.Equals("loc", StringComparison.Ordinal))
                    {
                        string locFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i);
                        if (String.IsNullOrEmpty(locFile))
                        {
                            break;
                        }

                        this.LocalizationFiles.Add(locFile);
                    }
                    else if (parameter.Equals("nologo", StringComparison.Ordinal))
                    {
                        this.ShowLogo = false;
                    }
                    else if (parameter.Equals("notidy", StringComparison.Ordinal))
                    {
                        this.Tidy = false;
                    }
                    else if ("o" == parameter || "out" == parameter)
                    {
                        this.OutputFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i);
                        if (String.IsNullOrEmpty(this.OutputFile))
                        {
                            break;
                        }
                    }
                    else if (parameter.Equals("pedantic", StringComparison.Ordinal))
                    {
                        this.ShowPedanticMessages = true;
                    }
                    else if (parameter.Equals("sloc", StringComparison.Ordinal))
                    {
                        this.SuppressLocalization = true;
                    }
                    else if (parameter.Equals("usf", StringComparison.Ordinal))
                    {
                        this.UnreferencedSymbolsFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i);

                        if (String.IsNullOrEmpty(this.UnreferencedSymbolsFile))
                        {
                            break;
                        }
                    }
                    else if (parameter.Equals("xo", StringComparison.Ordinal))
                    {
                        this.OutputXml = true;
                    }
                    else if (parameter.Equals("cc", StringComparison.Ordinal))
                    {
                        this.CabCachePath = CommandLineHelper.GetDirectory(parameter, this.Messaging, args, ++i);

                        if (String.IsNullOrEmpty(this.CabCachePath))
                        {
                            break;
                        }
                    }
                    else if (parameter.Equals("ct", StringComparison.Ordinal))
                    {
                        if (!CommandLineHelper.IsValidArg(args, ++i))
                        {
                            this.Messaging.Write(ErrorMessages.IllegalCabbingThreadCount(String.Empty));
                            break;
                        }

                        int ct = 0;
                        if (!Int32.TryParse(args[i], out ct) || 0 >= ct)
                        {
                            this.Messaging.Write(ErrorMessages.IllegalCabbingThreadCount(args[i]));
                            break;
                        }

                        this.CabbingThreadCount = ct;
                        this.Messaging.Write(VerboseMessages.SetCabbingThreadCount(this.CabbingThreadCount.ToString()));
                    }
                    else if (parameter.Equals("cub", StringComparison.Ordinal))
                    {
                        string cubeFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i);

                        if (String.IsNullOrEmpty(cubeFile))
                        {
                            break;
                        }

                        this.CubeFiles.Add(cubeFile);
                    }
                    else if (parameter.StartsWith("ice:", StringComparison.Ordinal))
                    {
                        this.Ices.Add(parameter.Substring(4));
                    }
                    else if (parameter.Equals("intermediatefolder", StringComparison.OrdinalIgnoreCase))
                    {
                        this.IntermediateFolder = CommandLineHelper.GetDirectory(parameter, this.Messaging, args, ++i);

                        if (String.IsNullOrEmpty(this.IntermediateFolder))
                        {
                            break;
                        }
                    }
                    else if (parameter.Equals("contentsfile", StringComparison.Ordinal))
                    {
                        this.ContentsFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i);

                        if (String.IsNullOrEmpty(this.ContentsFile))
                        {
                            break;
                        }
                    }
                    else if (parameter.Equals("outputsfile", StringComparison.Ordinal))
                    {
                        this.OutputsFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i);

                        if (String.IsNullOrEmpty(this.OutputsFile))
                        {
                            break;
                        }
                    }
                    else if (parameter.Equals("builtoutputsfile", StringComparison.Ordinal))
                    {
                        this.BuiltOutputsFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i);

                        if (String.IsNullOrEmpty(this.BuiltOutputsFile))
                        {
                            break;
                        }
                    }
                    else if (parameter.Equals("wixprojectfile", StringComparison.Ordinal))
                    {
                        this.WixprojectFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i);

                        if (String.IsNullOrEmpty(this.WixprojectFile))
                        {
                            break;
                        }
                    }
                    else if (parameter.Equals("pdbout", StringComparison.Ordinal))
                    {
                        this.PdbFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i);

                        if (String.IsNullOrEmpty(this.PdbFile))
                        {
                            break;
                        }
                    }
                    else if (parameter.StartsWith("sice:", StringComparison.Ordinal))
                    {
                        this.SuppressIces.Add(parameter.Substring(5));
                    }
                    else if (parameter.Equals("sl", StringComparison.Ordinal))
                    {
                        this.SuppressLayout = true;
                    }
                    else if (parameter.Equals("spdb", StringComparison.Ordinal))
                    {
                        this.SuppressWixPdb = true;
                    }
                    else if (parameter.Equals("sacl", StringComparison.Ordinal))
                    {
                        this.SuppressAclReset = true;
                    }
                    else if (parameter.Equals("sval", StringComparison.Ordinal))
                    {
                        this.SuppressValidation = true;
                    }
                    else if ("sv" == parameter)
                    {
                        this.SuppressVersionCheck = true;
                    }
                    else if (parameter.StartsWith("sw", StringComparison.Ordinal))
                    {
                        string paramArg = parameter.Substring(2);
                        if (0 == paramArg.Length)
                        {
                            this.Messaging.SuppressAllWarnings = true;
                        }
                        else
                        {
                            int suppressWarning = 0;
                            if (!Int32.TryParse(paramArg, out suppressWarning) || 0 >= suppressWarning)
                            {
                                this.Messaging.Write(ErrorMessages.IllegalSuppressWarningId(paramArg));
                            }
                            else
                            {
                                this.Messaging.SuppressWarningMessage(suppressWarning);
                            }
                        }
                    }
                    else if (parameter.StartsWith("wx", StringComparison.Ordinal))
                    {
                        string paramArg = parameter.Substring(2);
                        if (0 == paramArg.Length)
                        {
                            this.Messaging.WarningsAsError = true;
                        }
                        else
                        {
                            int elevateWarning = 0;
                            if (!Int32.TryParse(paramArg, out elevateWarning) || 0 >= elevateWarning)
                            {
                                this.Messaging.Write(ErrorMessages.IllegalWarningIdAsError(paramArg));
                            }
                            else
                            {
                                this.Messaging.ElevateWarningMessage(elevateWarning);
                            }
                        }
                    }
                    else if ("v" == parameter)
                    {
                        this.Messaging.ShowVerboseMessages = true;
                    }
                    else if ("?" == parameter || "help" == parameter)
                    {
                        this.ShowHelp = true;
                        break;
                    }
                    else
                    {
                        unprocessed.Add(arg);
                    }
                }
                else if ('@' == arg[0])
                {
                    string[] parsedArgs   = CommandLineResponseFile.Parse(arg.Substring(1));
                    string[] unparsedArgs = this.Parse(parsedArgs);
                    unprocessed.AddRange(unparsedArgs);
                }
                else
                {
                    unprocessed.Add(arg);
                }
            }

            return(unprocessed.ToArray());
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Parse the commandline arguments.
        /// </summary>
        /// <param name="args">Commandline arguments.</param>
        public string[] Parse(ICommandLineContext context)
        {
            var unprocessed = new List <string>();

            var extensions = context.ExtensionManager.Create <IExtensionCommandLine>();

            foreach (var extension in extensions)
            {
                extension.PreParse(context);
            }

            var parser = context.Arguments.Parse();

            while (!this.ShowHelp &&
                   String.IsNullOrEmpty(parser.ErrorArgument) &&
                   parser.TryGetNextSwitchOrArgument(out var arg))
            {
                if (String.IsNullOrWhiteSpace(arg)) // skip blank arguments.
                {
                    continue;
                }

                if (parser.IsSwitch(arg))
                {
                    var parameter = arg.Substring(1);
                    if (parameter.Equals("b", StringComparison.Ordinal))
                    {
                        var result = parser.GetNextArgumentOrError(arg);
                        if (!String.IsNullOrEmpty(result))
                        {
                            var bindPath = BindPath.Parse(result);

                            this.BindPaths.Add(bindPath);
                        }
                    }
                    else if (parameter.StartsWith("cultures:", StringComparison.Ordinal))
                    {
                        string culturesString = arg.Substring(10).ToLower(CultureInfo.InvariantCulture);

                        // When null is used treat it as if cultures wasn't specified.
                        // This is needed for batching over the light task when using MSBuild which doesn't
                        // support empty items
                        if (culturesString.Equals("null", StringComparison.OrdinalIgnoreCase))
                        {
                            this.Cultures = null;
                        }
                        else
                        {
                            this.Cultures = culturesString.Split(';', ',');

                            for (int c = 0; c < this.Cultures.Length; ++c)
                            {
                                // Neutral is different from null. For neutral we still want to do WXL filtering.
                                // Set the culture to the empty string = identifier for the invariant culture
                                if (this.Cultures[c].Equals("neutral", StringComparison.OrdinalIgnoreCase))
                                {
                                    this.Cultures[c] = String.Empty;
                                }
                            }
                        }
                    }
                    else if (parameter.StartsWith("dcl:", StringComparison.Ordinal))
                    {
                        string defaultCompressionLevel = arg.Substring(5);

                        if (String.IsNullOrEmpty(defaultCompressionLevel))
                        {
                            break;
                        }
                        else if (Enum.TryParse(defaultCompressionLevel, true, out CompressionLevel compressionLevel))
                        {
                            this.DefaultCompressionLevel = compressionLevel;
                        }
                    }
                    else if (parameter.StartsWith("d", StringComparison.Ordinal))
                    {
                        parameter = arg.Substring(2);
                        string[] value = parameter.Split("=".ToCharArray(), 2);

                        string preexisting;
                        if (1 == value.Length)
                        {
                            this.Messaging.Write(ErrorMessages.ExpectedWixVariableValue(value[0]));
                        }
                        else if (this.Variables.TryGetValue(value[0], out preexisting))
                        {
                            this.Messaging.Write(ErrorMessages.WixVariableCollision(null, value[0]));
                        }
                        else
                        {
                            this.Variables.Add(value[0], value[1]);
                        }
                    }
                    else if (parameter.Equals("loc", StringComparison.Ordinal))
                    {
                        parser.GetNextArgumentAsFilePathOrError(arg, "localization files", this.LocalizationFiles);
                    }
                    else if (parameter.Equals("nologo", StringComparison.Ordinal))
                    {
                        this.ShowLogo = false;
                    }
                    else if (parameter.Equals("notidy", StringComparison.Ordinal))
                    {
                        this.Tidy = false;
                    }
                    else if ("o" == parameter || "out" == parameter)
                    {
                        this.OutputFile = parser.GetNextArgumentAsFilePathOrError(arg);
                    }
                    else if (parameter.Equals("pedantic", StringComparison.Ordinal))
                    {
                        this.ShowPedanticMessages = true;
                    }
                    else if (parameter.Equals("sloc", StringComparison.Ordinal))
                    {
                        this.SuppressLocalization = true;
                    }
                    else if (parameter.Equals("usf", StringComparison.Ordinal))
                    {
                        this.UnreferencedSymbolsFile = parser.GetNextArgumentAsDirectoryOrError(arg);
                    }
                    else if (parameter.Equals("xo", StringComparison.Ordinal))
                    {
                        this.OutputXml = true;
                    }
                    else if (parameter.Equals("cc", StringComparison.Ordinal))
                    {
                        this.CabCachePath = parser.GetNextArgumentAsDirectoryOrError(arg);
                    }
                    else if (parameter.Equals("ct", StringComparison.Ordinal))
                    {
                        var result = parser.GetNextArgumentOrError(arg);
                        if (!String.IsNullOrEmpty(result))
                        {
                            if (!Int32.TryParse(result, out var ct) || 0 >= ct)
                            {
                                this.Messaging.Write(ErrorMessages.IllegalCabbingThreadCount(result));
                                parser.ErrorArgument = arg;
                                break;
                            }

                            this.CabbingThreadCount = ct;
                            this.Messaging.Write(VerboseMessages.SetCabbingThreadCount(this.CabbingThreadCount.ToString()));
                        }
                    }
                    else if (parameter.Equals("cub", StringComparison.Ordinal))
                    {
                        parser.GetNextArgumentAsFilePathOrError(arg, "static validation files", this.CubeFiles);
                    }
                    else if (parameter.StartsWith("ice:", StringComparison.Ordinal))
                    {
                        this.Ices.Add(parameter.Substring(4));
                    }
                    else if (parameter.Equals("intermediatefolder", StringComparison.OrdinalIgnoreCase))
                    {
                        this.IntermediateFolder = parser.GetNextArgumentAsDirectoryOrError(arg);
                    }
                    else if (parameter.Equals("contentsfile", StringComparison.Ordinal))
                    {
                        this.ContentsFile = parser.GetNextArgumentAsFilePathOrError(arg);
                    }
                    else if (parameter.Equals("outputsfile", StringComparison.Ordinal))
                    {
                        this.OutputsFile = parser.GetNextArgumentAsFilePathOrError(arg);
                    }
                    else if (parameter.Equals("builtoutputsfile", StringComparison.Ordinal))
                    {
                        this.BuiltOutputsFile = parser.GetNextArgumentAsFilePathOrError(arg);
                    }
                    else if (parameter.Equals("wixprojectfile", StringComparison.Ordinal))
                    {
                        this.WixprojectFile = parser.GetNextArgumentAsFilePathOrError(arg);
                    }
                    else if (parameter.Equals("pdbout", StringComparison.Ordinal))
                    {
                        this.PdbFile = parser.GetNextArgumentAsFilePathOrError(arg);
                    }
                    else if (parameter.StartsWith("sice:", StringComparison.Ordinal))
                    {
                        this.SuppressIces.Add(parameter.Substring(5));
                    }
                    else if (parameter.Equals("sl", StringComparison.Ordinal))
                    {
                        this.SuppressLayout = true;
                    }
                    else if (parameter.Equals("spdb", StringComparison.Ordinal))
                    {
                        this.SuppressWixPdb = true;
                    }
                    else if (parameter.Equals("sacl", StringComparison.Ordinal))
                    {
                        this.SuppressAclReset = true;
                    }
                    else if (parameter.Equals("sval", StringComparison.Ordinal))
                    {
                        this.SuppressValidation = true;
                    }
                    else if ("sv" == parameter)
                    {
                        this.SuppressVersionCheck = true;
                    }
                    else if (parameter.StartsWith("sw", StringComparison.Ordinal))
                    {
                        string paramArg = parameter.Substring(2);
                        if (0 == paramArg.Length)
                        {
                            this.Messaging.SuppressAllWarnings = true;
                        }
                        else
                        {
                            int suppressWarning = 0;
                            if (!Int32.TryParse(paramArg, out suppressWarning) || 0 >= suppressWarning)
                            {
                                this.Messaging.Write(ErrorMessages.IllegalSuppressWarningId(paramArg));
                            }
                            else
                            {
                                this.Messaging.SuppressWarningMessage(suppressWarning);
                            }
                        }
                    }
                    else if (parameter.StartsWith("wx", StringComparison.Ordinal))
                    {
                        string paramArg = parameter.Substring(2);
                        if (0 == paramArg.Length)
                        {
                            this.Messaging.WarningsAsError = true;
                        }
                        else
                        {
                            int elevateWarning = 0;
                            if (!Int32.TryParse(paramArg, out elevateWarning) || 0 >= elevateWarning)
                            {
                                this.Messaging.Write(ErrorMessages.IllegalWarningIdAsError(paramArg));
                            }
                            else
                            {
                                this.Messaging.ElevateWarningMessage(elevateWarning);
                            }
                        }
                    }
                    else if ("v" == parameter)
                    {
                        this.Messaging.ShowVerboseMessages = true;
                    }
                    else if ("?" == parameter || "help" == parameter)
                    {
                        this.ShowHelp = true;
                        break;
                    }
                    else if (!this.TryParseCommandLineArgumentWithExtension(arg, parser, extensions))
                    {
                        unprocessed.Add(arg);
                    }
                }
                else if (!this.TryParseCommandLineArgumentWithExtension(arg, parser, extensions))
                {
                    unprocessed.Add(arg);
                }
            }

            return(this.ParsePostExtensions(parser, unprocessed.ToArray()));
        }