示例#1
0
文件: Test.cs 项目: deathcap/jison
		public static void Main()
		{
            Spreadsheet.Spreadsheets = new SpreadsheetsDictionary();
		    var spreadsheetsDictionary = new SpreadsheetDictionary();
            Spreadsheet.Spreadsheets.Add(0, spreadsheetsDictionary);
		    var row = new RowDictionary();
            spreadsheetsDictionary.Add(0, row);

		    var cellA1 = new Cell(0, 0, 0);
		    cellA1.Value = "250";
		    var cellB1 = new Cell(0, 0, 1);
            cellB1.Value = "250";
		    var cellC1 = new Cell(0, 0, 2);
            cellC1.Formula = "800 - SUM(A1:B1) + 100";
		    cellC1.HasFormula = true;

            row.Add(0, cellA1);
            row.Add(1, cellB1);
            row.Add(2, cellC1);

            //var spreadsheet = new Spreadsheet();
		    //spreadsheet.Calc();

		    var parsedCell = Spreadsheet.Spreadsheets[0][0][2];
		    var value = parsedCell.UpdateValue();
		    value = value;
		}
示例#2
0
        public void WhenTryingToGetAValueAndTheKeyExistsShould()
        {
            //Arrange
            var key                         = 01;
            var expectedValue               = "expectedValue";
            var comparer                    = Comparer <int> .Default;
            var mockEqualityService         = MockRepository.GenerateMock <IComparer <Cell <int, string> > >();
            var mockEqualityServiceProvider = MockRepository.GenerateMock <IEqualityServiceProvider <int> >();

            mockEqualityServiceProvider.Stub(x => x.GetKeyComparer(comparer)).Return(comparer);
            mockEqualityService
            .Stub(s => s.Compare(
                      Arg <Cell <int, string> > .Matches(x => x.Key == key),
                      Arg <Cell <int, string> > .Matches(x => x.Key == key)))
            .Return(0);
            var sut = new RowDictionary <int, string>(comparer, mockEqualityServiceProvider);

            sut.Add(key, expectedValue);
            string resultValue;

            //Act
            var resultBooleanValue = sut.TryGetValue(key, out resultValue);

            //Assert
            Assert.That(resultBooleanValue, Is.True);
            Assert.That(resultValue, Is.EqualTo(expectedValue));
        }
示例#3
0
        public void WhenTryingToGetAValueAndTheKeyDoesNotExistShould()
        {
            //Arrange
            var key = "key";
            var thisKeyDoesNotExist         = "thisKeyDoesNotExist";
            var expectedValue               = "expectedValue";
            var comparer                    = (IComparer <string>)StringComparer.InvariantCultureIgnoreCase;
            var mockEqualityService         = MockRepository.GenerateMock <IComparer <Cell <string, string> > >();
            var mockEqualityServiceProvider = MockRepository.GenerateMock <IEqualityServiceProvider <string> >();

            mockEqualityServiceProvider.Stub(x => x.GetKeyComparer(comparer)).Return(comparer);
            mockEqualityService
            .Stub(s => s.Compare(
                      Arg <Cell <string, string> > .Matches(x => x.Key == key),
                      Arg <Cell <string, string> > .Matches(x => x.Key == thisKeyDoesNotExist)))
            .Return(-1);

            var sut = new RowDictionary <string, string>(comparer, mockEqualityServiceProvider);

            sut.Add(key, expectedValue);
            string resultValue;

            //Act
            var resultBooleanValue = sut.TryGetValue(thisKeyDoesNotExist, out resultValue);

            //Assert
            Assert.That(resultBooleanValue, Is.False);
        }
示例#4
0
        public void ShouldBeAbleToRetrieveTheValueUsingTheKeyWhenThereIsMoreThanOneValueInserted()
        {
            //Arrange
            var key           = 04;
            var expectedValue = "expectedValue";
            var sut           = new RowDictionary <int, string>();

            sut.Add(01, "01");
            sut.Add(02, "02");
            sut.Add(03, "03");
            sut.Add(key, expectedValue);
            string result;

            //Act
            sut.TryGetValue(key, out result);

            //Assert
            Assert.That(result, Is.EqualTo(expectedValue));
        }
示例#5
0
        public static RowDictionary RowsToDict(RowsRet rows)
        {
            RowDictionary rowDict =
                new RowDictionary();

            List <string> .Enumerator headerRow =
                rows.Rows[0].Cols.GetEnumerator();

            foreach (string cell in rows.Rows[1].Cols)
            {
                headerRow.MoveNext();
                rowDict.Add(headerRow.Current, cell);
            }
            return(rowDict);
        }
示例#6
0
        public void ShouldBeAbleToAddANewValueAndRetriveTheSameValueUsingTheSameKey()
        {
            //Arrange
            var key           = "key";
            var expectedValue = "Hola mundo";
            var sut           = new RowDictionary <string, string>();

            sut.Add(key, expectedValue);
            string result;

            //Act
            sut.TryGetValue(key, out result);

            //Assert
            Assert.That(result, Is.EqualTo(expectedValue));
        }
示例#7
0
        public void ShouldBeAbleToRetrieveTheValueUsingTheKeyWhenTheKeyIsNonPrimitive()
        {
            //Arrange
            var          myKey = new { FirstName = "ABC", LastName = "DFG" };
            const string whenTheKeyIsAnObject = "WhenTheKeyIsAnObject";
            var          sut = new RowDictionary <object, string>();

            sut.Add(myKey, whenTheKeyIsAnObject);
            string result;

            //Act
            sut.TryGetValue(myKey, out result);

            //Assert
            Assert.That(result, Is.EqualTo(whenTheKeyIsAnObject));
        }
示例#8
0
        public static RowDictionary RowsToDict(Row header, Row row)
        {
            RowDictionary rowDict =
                new RowDictionary();

            List <string> .Enumerator headerRow =
                header.Cols.GetEnumerator();

            foreach (string cell in row.Cols)
            {
                headerRow.MoveNext();
                if (!rowDict.ContainsKey(headerRow.Current))
                {
                    rowDict.Add(headerRow.Current, cell);
                }
            }

            return(rowDict);
        }
示例#9
0
        public void WhenGettingAValueAndTheKeyExistsShould()
        {
            //Arrange
            var key           = 01;
            var expectedValue = "expectedValue";
            var comparer      = Comparer <int> .Default;
            var mockEqualityServiceProvider = MockRepository.GenerateMock <IEqualityServiceProvider <int> >();

            mockEqualityServiceProvider.Stub(x => x.GetKeyComparer(comparer)).Return(comparer);
            var sut = new RowDictionary <int, string>(comparer, mockEqualityServiceProvider);

            sut.Add(key, expectedValue);
            string resultValue;

            //Act
            resultValue = sut[key];

            //Assert
            Assert.That(resultValue, Is.EqualTo(expectedValue));
        }
示例#10
0
        public void ShouldIterateExactlyAsManyTimesAsKeysAdded()
        {
            //Arrange
            var sut = new RowDictionary <int, string>();

            sut.Add(01, "Value01");
            sut.Add(02, "Value02");
            sut.Add(03, "Value03");
            sut.Add(04, "Value04");
            sut.Add(05, "Value05");
            sut.Add(06, "Value06");

            //Act
            var totalItems = sut.Cast <object>().Count();

            //Assert
            Assert.That(totalItems, Is.EqualTo(6));
        }
示例#11
0
        /// <summary>
        /// Assign files to cabinets based on Media authoring.
        /// </summary>
        /// <param name="mediaTable"></param>
        /// <param name="mergeModuleMediaRow"></param>
        /// <param name="fileFacades"></param>
        private void ManuallyAssignFiles(Table mediaTable, MediaRow mergeModuleMediaRow, IEnumerable <FileFacade> fileFacades, Dictionary <MediaRow, List <FileFacade> > filesByCabinetMedia, RowDictionary <MediaRow> mediaRows, List <FileFacade> uncompressedFiles)
        {
            if (OutputType.Module != this.Output.Type)
            {
                if (null != mediaTable)
                {
                    Dictionary <string, MediaRow> cabinetMediaRows = new Dictionary <string, MediaRow>(StringComparer.InvariantCultureIgnoreCase);
                    foreach (MediaRow mediaRow in mediaTable.Rows)
                    {
                        // If the Media row has a cabinet, make sure it is unique across all Media rows.
                        if (!String.IsNullOrEmpty(mediaRow.Cabinet))
                        {
                            MediaRow existingRow;
                            if (cabinetMediaRows.TryGetValue(mediaRow.Cabinet, out existingRow))
                            {
                                Messaging.Instance.OnMessage(WixErrors.DuplicateCabinetName(mediaRow.SourceLineNumbers, mediaRow.Cabinet));
                                Messaging.Instance.OnMessage(WixErrors.DuplicateCabinetName2(existingRow.SourceLineNumbers, existingRow.Cabinet));
                            }
                            else
                            {
                                cabinetMediaRows.Add(mediaRow.Cabinet, mediaRow);
                            }
                        }

                        mediaRows.Add(mediaRow);
                    }
                }

                foreach (MediaRow mediaRow in mediaRows.Values)
                {
                    if (null != mediaRow.Cabinet)
                    {
                        filesByCabinetMedia.Add(mediaRow, new List <FileFacade>());
                    }
                }
            }

            foreach (FileFacade facade in fileFacades)
            {
                if (OutputType.Module == this.Output.Type)
                {
                    filesByCabinetMedia[mergeModuleMediaRow].Add(facade);
                }
                else
                {
                    MediaRow mediaRow;
                    if (!mediaRows.TryGetValue(facade.WixFile.DiskId.ToString(CultureInfo.InvariantCulture), out mediaRow))
                    {
                        Messaging.Instance.OnMessage(WixErrors.MissingMedia(facade.File.SourceLineNumbers, facade.WixFile.DiskId));
                        continue;
                    }

                    // When building a product, if the current file is not to be compressed or if
                    // the package set not to be compressed, don't cab it.
                    if (OutputType.Product == this.Output.Type &&
                        (YesNoType.No == facade.File.Compressed ||
                         (YesNoType.NotSet == facade.File.Compressed && !this.FilesCompressed)))
                    {
                        uncompressedFiles.Add(facade);
                    }
                    else // file is marked compressed.
                    {
                        List <FileFacade> cabinetFiles;
                        if (filesByCabinetMedia.TryGetValue(mediaRow, out cabinetFiles))
                        {
                            cabinetFiles.Add(facade);
                        }
                        else
                        {
                            Messaging.Instance.OnMessage(WixErrors.ExpectedMediaCabinet(facade.File.SourceLineNumbers, facade.File.File, facade.WixFile.DiskId));
                        }
                    }
                }
            }
        }
示例#12
0
        /// <summary>
        /// Assign files to cabinets based on MediaTemplate authoring.
        /// </summary>
        /// <param name="fileFacades">FileRowCollection</param>
        private void AutoAssignFiles(Table mediaTable, IEnumerable <FileFacade> fileFacades, Dictionary <MediaRow, List <FileFacade> > filesByCabinetMedia, RowDictionary <MediaRow> mediaRows, List <FileFacade> uncompressedFiles)
        {
            const int MaxCabIndex = 999;

            ulong currentPreCabSize = 0;
            ulong maxPreCabSizeInBytes;
            int   maxPreCabSizeInMB = 0;
            int   currentCabIndex   = 0;

            MediaRow currentMediaRow = null;

            Table mediaTemplateTable = this.Output.Tables["WixMediaTemplate"];

            // Auto assign files to cabinets based on maximum uncompressed media size
            mediaTable.Rows.Clear();
            WixMediaTemplateRow mediaTemplateRow = (WixMediaTemplateRow)mediaTemplateTable.Rows[0];

            if (!String.IsNullOrEmpty(mediaTemplateRow.CabinetTemplate))
            {
                this.CabinetNameTemplate = mediaTemplateRow.CabinetTemplate;
            }

            string mumsString = Environment.GetEnvironmentVariable("WIX_MUMS");

            try
            {
                // Override authored mums value if environment variable is authored.
                if (!String.IsNullOrEmpty(mumsString))
                {
                    maxPreCabSizeInMB = Int32.Parse(mumsString);
                }
                else
                {
                    maxPreCabSizeInMB = mediaTemplateRow.MaximumUncompressedMediaSize;
                }

                maxPreCabSizeInBytes = (ulong)maxPreCabSizeInMB * 1024 * 1024;
            }
            catch (FormatException)
            {
                throw new WixException(WixErrors.IllegalEnvironmentVariable("WIX_MUMS", mumsString));
            }
            catch (OverflowException)
            {
                throw new WixException(WixErrors.MaximumUncompressedMediaSizeTooLarge(null, maxPreCabSizeInMB));
            }

            foreach (FileFacade facade in this.FileFacades)
            {
                // When building a product, if the current file is not to be compressed or if
                // the package set not to be compressed, don't cab it.
                if (OutputType.Product == this.Output.Type &&
                    (YesNoType.No == facade.File.Compressed ||
                     (YesNoType.NotSet == facade.File.Compressed && !this.FilesCompressed)))
                {
                    uncompressedFiles.Add(facade);
                    continue;
                }

                if (currentCabIndex == MaxCabIndex)
                {
                    // Associate current file with last cab (irrespective of the size) and cab index is not incremented anymore.
                    List <FileFacade> cabinetFiles = filesByCabinetMedia[currentMediaRow];
                    facade.WixFile.DiskId = currentCabIndex;
                    cabinetFiles.Add(facade);
                    continue;
                }

                // Update current cab size.
                currentPreCabSize += (ulong)facade.File.FileSize;

                if (currentPreCabSize > maxPreCabSizeInBytes)
                {
                    // Overflow due to current file
                    currentMediaRow = this.AddMediaRow(mediaTemplateRow, mediaTable, ++currentCabIndex);
                    mediaRows.Add(currentMediaRow);
                    filesByCabinetMedia.Add(currentMediaRow, new List <FileFacade>());

                    List <FileFacade> cabinetFileRows = filesByCabinetMedia[currentMediaRow];
                    facade.WixFile.DiskId = currentCabIndex;
                    cabinetFileRows.Add(facade);
                    // Now files larger than MaxUncompressedMediaSize will be the only file in its cabinet so as to respect MaxUncompressedMediaSize
                    currentPreCabSize = (ulong)facade.File.FileSize;
                }
                else
                {
                    // File fits in the current cab.
                    if (currentMediaRow == null)
                    {
                        // Create new cab and MediaRow
                        currentMediaRow = this.AddMediaRow(mediaTemplateRow, mediaTable, ++currentCabIndex);
                        mediaRows.Add(currentMediaRow);
                        filesByCabinetMedia.Add(currentMediaRow, new List <FileFacade>());
                    }

                    // Associate current file with current cab.
                    List <FileFacade> cabinetFiles = filesByCabinetMedia[currentMediaRow];
                    facade.WixFile.DiskId = currentCabIndex;
                    cabinetFiles.Add(facade);
                }
            }

            // If there are uncompressed files and no MediaRow, create a default one.
            if (uncompressedFiles.Count > 0 && mediaTable.Rows.Count == 0)
            {
                MediaRow defaultMediaRow = (MediaRow)mediaTable.CreateRow(null);
                defaultMediaRow.DiskId = 1;
                mediaRows.Add(defaultMediaRow);
            }
        }
示例#13
0
        public Cell AddCells_Old_2(Cell cell, InstanceFact fact, Table table)
        {
            var dynamiccell = new Cell();

            dynamiccell.Report    = cell.Report;
            dynamiccell.Extension = cell.Extension;
            dynamiccell.Row       = cell.Row;
            dynamiccell.Column    = cell.Column;

            if (fact.Dimensions.Count == 0)
            {
                var factstring = Instance.GetFactStringKey(fact.InstanceKey);
                var tmpfact    = new FactBase();
                tmpfact.SetFromString(factstring);
                fact.Dimensions.AddRange(tmpfact.Dimensions);
            }

            if (cell.Extension == Literals.DynamicCode)
            {
                var ext            = table.Extensions.Children.FirstOrDefault();
                var opendimensions = ext.Item.Dimensions.Where(i => String.IsNullOrEmpty(i.DomainMember)).ToList();

                //var typeddimensions = ext.Item.Dimensions.Where(i => i.IsTyped).ToList();
                //var axistypeddimensions = Dimension.GetDimensions(fact.Dimensions, typeddimensions);

                var instanceopendimensions = Dimension.GetDimensions(fact.Dimensions, opendimensions);
                var openfactstring         = GetFactString(instanceopendimensions);

                if (!ExtDictionary.ContainsKey(openfactstring))
                {
                    var extnr = String.Format("{0}", ExtDictionary.Count + 1);
                    ExtDictionary.Add(openfactstring, extnr);
                }
                dynamiccell.Extension = ExtDictionary[openfactstring];
            }
            if (cell.Row == Literals.DynamicCode)
            {
                // var cell = table.Rows

                var row                 = table.Rows.FirstOrDefault(i => i.Item.LabelCode == cell.Row);
                var typeddimensions     = row.Item.Dimensions.Where(i => i.IsTyped).ToList();
                var axistypeddimensions = Dimension.GetDimensions(fact.Dimensions, typeddimensions);
                var typedfactstring     = GetTypedFactString(axistypeddimensions);

                if (!RowDictionary.ContainsKey(typedfactstring))
                {
                    var rownr = String.Format("{0}", RowDictionary.Count + 1);
                    RowDictionary.Add(typedfactstring, rownr);
                }
                dynamiccell.Row = RowDictionary[typedfactstring];
            }
            if (cell.Column == Literals.DynamicCode)
            {
                // var cell = table.Rows

                var col                 = table.Columns.FirstOrDefault(i => i.Item.LabelCode == cell.Row);
                var typeddimensions     = col.Item.Dimensions.Where(i => i.IsTyped).ToList();
                var axistypeddimensions = Dimension.GetDimensions(fact.Dimensions, typeddimensions);
                var typedfactstring     = GetTypedFactString(axistypeddimensions);

                if (!ColDictionary.ContainsKey(typedfactstring))
                {
                    var rownr = String.Format("{0}", RowDictionary.Count + 1);
                    ColDictionary.Add(typedfactstring, rownr);
                }
                dynamiccell.Column = ColDictionary[typedfactstring];
            }
            //if (dynamiccell.CellID != cell.CellID)
            //{
            //    //var cellfactstring = fact.FactString;
            //    //if (CellOfFact.ContainsKey(fact.FactString))
            //    //if (1 == 2)
            //    //{
            //    //    //var existing = CellOfFact[fact.FactString];

            //    //    var existingfacts = TaxonomyEngine.CurrentEngine.CurrentInstance.FactDictionary.FactsByTaxonomyKey[fact.InstanceKey];
            //    //    //var existingfact = existingfacts.FirstOrDefault(i => i.FactString == fact.FactString);
            //    //    var ctid = typeof(InstanceFact).IsAssignableFrom(fact.GetType()) ? ((InstanceFact)fact).ContextID : "";
            //    //    var msg = String.Format("Fact {0} already exist >> {1}!", fact, ctid);
            //    //    Utilities.Logger.WriteLine(msg);
            //    //}
            //    //else
            //    //{
            //    //    //var item = this.Instance.FactDictionary[fact.FactIntkeys];
            //    //    //CellOfFact.Add(fact.FactString, dynamiccell.CellID);
            //    //}
            //}
            //else
            //{

            //}
            fact.Cells.Add(dynamiccell.CellID);

            return(dynamiccell);
        }
示例#14
0
        public Cell AddCells(Cell cell, InstanceFact fact, Table table)
        {
            var dynamiccell = new Cell();

            dynamiccell.Report    = cell.Report;
            dynamiccell.Extension = cell.Extension;
            dynamiccell.Row       = cell.Row;
            dynamiccell.Column    = cell.Column;

            if (cell.Extension == Literals.DynamicCode)
            {
                var ext = table.Extensions.Children.FirstOrDefault();

                var opendimensions = ext.Item.Dimensions.Where(i => i.MapID == i.DomMapID).Select(i => i.MapID).ToList();

                var instanceopendimensions = GetInstanceAspects(Instance, fact, opendimensions);
                var openfactstring         = GetString(instanceopendimensions);

                if (!ExtDictionary.ContainsKey(openfactstring))
                {
                    var extnr = String.Format("{0}", ExtDictionary.Count + 1);
                    ExtDictionary.Add(openfactstring, extnr);
                }
                dynamiccell.Extension = ExtDictionary[openfactstring];
            }
            if (cell.Row == Literals.DynamicCode)
            {
                // var cell = table.Rows

                var row = table.Rows.FirstOrDefault(i => i.Item.LabelCode == cell.Row);

                var opendimensions = row.Item.Dimensions.Where(i => i.MapID == i.DomMapID).Select(i => i.MapID).ToList();

                var instanceopendimensions = GetInstanceAspects(Instance, fact, opendimensions);
                var openfactstring         = GetString(instanceopendimensions);

                if (!RowDictionary.ContainsKey(openfactstring))
                {
                    var rownr = String.Format("{0}", RowDictionary.Count + 1);
                    RowDictionary.Add(openfactstring, rownr);
                }
                dynamiccell.Row = RowDictionary[openfactstring];
            }
            if (cell.Column == Literals.DynamicCode)
            {
                // var cell = table.Rows

                var col = table.Columns.FirstOrDefault(i => i.Item.LabelCode == cell.Row);

                var opendimensions = col.Item.Dimensions.Where(i => i.MapID == i.DomMapID).Select(i => i.MapID).ToList();

                var instanceopendimensions = GetInstanceAspects(Instance, fact, opendimensions);
                var openfactstring         = GetString(instanceopendimensions);

                if (!ColDictionary.ContainsKey(openfactstring))
                {
                    var rownr = String.Format("{0}", RowDictionary.Count + 1);
                    ColDictionary.Add(openfactstring, rownr);
                }
                dynamiccell.Column = ColDictionary[openfactstring];
            }
            if (dynamiccell.CellID != cell.CellID)
            {
            }
            else
            {
            }
            fact.Cells.Add(dynamiccell.CellID);

            return(dynamiccell);
        }
示例#15
0
        public void Execute()
        {
            throw new NotImplementedException();
#if TODO
            this.FileTransfers    = Enumerable.Empty <FileTransfer>();
            this.ContentFilePaths = Enumerable.Empty <string>();

            // First look for data we expect to find... Chain, WixGroups, etc.

            // We shouldn't really get past the linker phase if there are
            // no group items... that means that there's no UX, no Chain,
            // *and* no Containers!
            Table chainPackageTable = this.GetRequiredTable("WixBundlePackage");

            Table wixGroupTable = this.GetRequiredTable("WixGroup");

            // Ensure there is one and only one row in the WixBundle table.
            // The compiler and linker behavior should have colluded to get
            // this behavior.
            WixBundleRow bundleRow = (WixBundleRow)this.GetSingleRowTable("WixBundle");

            bundleRow.PerMachine = true; // default to per-machine but the first-per user package wil flip the bundle per-user.

            // Ensure there is one and only one row in the WixBootstrapperApplication table.
            // The compiler and linker behavior should have colluded to get
            // this behavior.
            Row baRow = this.GetSingleRowTable("WixBootstrapperApplication");

            // Ensure there is one and only one row in the WixChain table.
            // The compiler and linker behavior should have colluded to get
            // this behavior.
            WixChainRow chainRow = (WixChainRow)this.GetSingleRowTable("WixChain");

            if (Messaging.Instance.EncounteredError)
            {
                return;
            }

            // If there are any fields to resolve later, create the cache to populate during bind.
            IDictionary <string, string> variableCache = null;
            if (this.DelayedFields.Any())
            {
                variableCache = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase);
            }

            // TODO: Although the WixSearch tables are defined in the Util extension,
            // the Bundle Binder has to know all about them. We hope to revisit all
            // of this in the 4.0 timeframe.
            IEnumerable <WixSearchInfo> orderedSearches = this.OrderSearches();

            // Extract files that come from cabinet files (this does not extract files from merge modules).
            {
                var extractEmbeddedFilesCommand = new ExtractEmbeddedFilesCommand();
                extractEmbeddedFilesCommand.FilesWithEmbeddedFiles = ExpectedEmbeddedFiles;
                extractEmbeddedFilesCommand.Execute();
            }

            // Get the explicit payloads.
            RowDictionary <WixBundlePayloadRow> payloads = new RowDictionary <WixBundlePayloadRow>(this.Output.Tables["WixBundlePayload"]);

            // Update explicitly authored payloads with their parent package and container (as appropriate)
            // to make it easier to gather the payloads later.
            foreach (WixGroupRow row in wixGroupTable.RowsAs <WixGroupRow>())
            {
                if (ComplexReferenceChildType.Payload == row.ChildType)
                {
                    WixBundlePayloadRow payload = payloads.Get(row.ChildId);

                    if (ComplexReferenceParentType.Package == row.ParentType)
                    {
                        Debug.Assert(String.IsNullOrEmpty(payload.Package));
                        payload.Package = row.ParentId;
                    }
                    else if (ComplexReferenceParentType.Container == row.ParentType)
                    {
                        Debug.Assert(String.IsNullOrEmpty(payload.Container));
                        payload.Container = row.ParentId;
                    }
                    else if (ComplexReferenceParentType.Layout == row.ParentType)
                    {
                        payload.LayoutOnly = true;
                    }
                }
            }

            List <FileTransfer> fileTransfers = new List <FileTransfer>();
            string layoutDirectory            = Path.GetDirectoryName(this.OutputPath);

            // Process the explicitly authored payloads.
            ISet <string> processedPayloads;
            {
                ProcessPayloadsCommand command = new ProcessPayloadsCommand();
                command.Payloads         = payloads.Values;
                command.DefaultPackaging = bundleRow.DefaultPackagingType;
                command.LayoutDirectory  = layoutDirectory;
                command.Execute();

                fileTransfers.AddRange(command.FileTransfers);

                processedPayloads = new HashSet <string>(payloads.Keys);
            }

            IDictionary <string, PackageFacade> facades;
            {
                GetPackageFacadesCommand command = new GetPackageFacadesCommand();
                command.PackageTable    = chainPackageTable;
                command.ExePackageTable = this.Output.Tables["WixBundleExePackage"];
                command.MsiPackageTable = this.Output.Tables["WixBundleMsiPackage"];
                command.MspPackageTable = this.Output.Tables["WixBundleMspPackage"];
                command.MsuPackageTable = this.Output.Tables["WixBundleMsuPackage"];
                command.Execute();

                facades = command.PackageFacades;
            }

            // Process each package facade. Note this is likely to add payloads and other rows to tables so
            // note that any indexes created above may be out of date now.
            foreach (PackageFacade facade in facades.Values)
            {
                switch (facade.Package.Type)
                {
                case WixBundlePackageType.Exe:
                {
                    ProcessExePackageCommand command = new ProcessExePackageCommand();
                    command.AuthoredPayloads = payloads;
                    command.Facade           = facade;
                    command.Execute();

                    // ? variableCache.Add(String.Concat("packageManufacturer.", facade.Package.WixChainItemId), facade.ExePackage.Manufacturer);
                }
                break;

                case WixBundlePackageType.Msi:
                {
                    var command = new ProcessMsiPackageCommand();
                    command.AuthoredPayloads    = payloads;
                    command.Facade              = facade;
                    command.BackendExtensions   = this.BackendExtensions;
                    command.MsiFeatureTable     = this.Output.EnsureTable(this.TableDefinitions["WixBundleMsiFeature"]);
                    command.MsiPropertyTable    = this.Output.EnsureTable(this.TableDefinitions["WixBundleMsiProperty"]);
                    command.PayloadTable        = this.Output.Tables["WixBundlePayload"];
                    command.RelatedPackageTable = this.Output.EnsureTable(this.TableDefinitions["WixBundleRelatedPackage"]);
                    command.Execute();

                    if (null != variableCache)
                    {
                        variableCache.Add(String.Concat("packageLanguage.", facade.Package.WixChainItemId), facade.MsiPackage.ProductLanguage.ToString());

                        if (null != facade.MsiPackage.Manufacturer)
                        {
                            variableCache.Add(String.Concat("packageManufacturer.", facade.Package.WixChainItemId), facade.MsiPackage.Manufacturer);
                        }
                    }
                }
                break;

                case WixBundlePackageType.Msp:
                {
                    ProcessMspPackageCommand command = new ProcessMspPackageCommand();
                    command.AuthoredPayloads = payloads;
                    command.Facade           = facade;
                    command.WixBundlePatchTargetCodeTable = this.Output.EnsureTable(this.TableDefinitions["WixBundlePatchTargetCode"]);
                    command.Execute();
                }
                break;

                case WixBundlePackageType.Msu:
                {
                    ProcessMsuPackageCommand command = new ProcessMsuPackageCommand();
                    command.Facade = facade;
                    command.Execute();
                }
                break;
                }

                if (null != variableCache)
                {
                    BindBundleCommand.PopulatePackageVariableCache(facade.Package, variableCache);
                }
            }

            // Reindex the payloads now that all the payloads (minus the manifest payloads that will be created later)
            // are present.
            payloads = new RowDictionary <WixBundlePayloadRow>(this.Output.Tables["WixBundlePayload"]);

            // Process the payloads that were added by processing the packages.
            {
                ProcessPayloadsCommand command = new ProcessPayloadsCommand();
                command.Payloads         = payloads.Values.Where(r => !processedPayloads.Contains(r.Id)).ToList();
                command.DefaultPackaging = bundleRow.DefaultPackagingType;
                command.LayoutDirectory  = layoutDirectory;
                command.Execute();

                fileTransfers.AddRange(command.FileTransfers);

                processedPayloads = null;
            }

            // Set the package metadata from the payloads now that we have the complete payload information.
            ILookup <string, WixBundlePayloadRow> payloadsByPackage = payloads.Values.ToLookup(p => p.Package);

            {
                foreach (PackageFacade facade in facades.Values)
                {
                    facade.Package.Size = 0;

                    IEnumerable <WixBundlePayloadRow> packagePayloads = payloadsByPackage[facade.Package.WixChainItemId];

                    foreach (WixBundlePayloadRow payload in packagePayloads)
                    {
                        facade.Package.Size += payload.FileSize;
                    }

                    if (!facade.Package.InstallSize.HasValue)
                    {
                        facade.Package.InstallSize = facade.Package.Size;
                    }

                    WixBundlePayloadRow packagePayload = payloads[facade.Package.PackagePayload];

                    if (String.IsNullOrEmpty(facade.Package.Description))
                    {
                        facade.Package.Description = packagePayload.Description;
                    }

                    if (String.IsNullOrEmpty(facade.Package.DisplayName))
                    {
                        facade.Package.DisplayName = packagePayload.DisplayName;
                    }
                }
            }


            // Give the UX payloads their embedded IDs...
            int uxPayloadIndex = 0;
            {
                foreach (WixBundlePayloadRow payload in payloads.Values.Where(p => Compiler.BurnUXContainerId == p.Container))
                {
                    // In theory, UX payloads could be embedded in the UX CAB, external to the bundle EXE, or even
                    // downloaded. The current engine requires the UX to be fully present before any downloading starts,
                    // so that rules out downloading. Also, the burn engine does not currently copy external UX payloads
                    // into the temporary UX directory correctly, so we don't allow external either.
                    if (PackagingType.Embedded != payload.Packaging)
                    {
                        Messaging.Instance.OnMessage(WixWarnings.UxPayloadsOnlySupportEmbedding(payload.SourceLineNumbers, payload.FullFileName));
                        payload.Packaging = PackagingType.Embedded;
                    }

                    payload.EmbeddedId = String.Format(CultureInfo.InvariantCulture, BurnCommon.BurnUXContainerEmbeddedIdFormat, uxPayloadIndex);
                    ++uxPayloadIndex;
                }

                if (0 == uxPayloadIndex)
                {
                    // If we didn't get any UX payloads, it's an error!
                    throw new WixException(WixErrors.MissingBundleInformation("BootstrapperApplication"));
                }

                // Give the embedded payloads without an embedded id yet an embedded id.
                int payloadIndex = 0;
                foreach (WixBundlePayloadRow payload in payloads.Values)
                {
                    Debug.Assert(PackagingType.Unknown != payload.Packaging);

                    if (PackagingType.Embedded == payload.Packaging && String.IsNullOrEmpty(payload.EmbeddedId))
                    {
                        payload.EmbeddedId = String.Format(CultureInfo.InvariantCulture, BurnCommon.BurnAttachedContainerEmbeddedIdFormat, payloadIndex);
                        ++payloadIndex;
                    }
                }
            }

            // Determine patches to automatically slipstream.
            {
                AutomaticallySlipstreamPatchesCommand command = new AutomaticallySlipstreamPatchesCommand();
                command.PackageFacades                = facades.Values;
                command.SlipstreamMspTable            = this.Output.EnsureTable(this.TableDefinitions["WixBundleSlipstreamMsp"]);
                command.WixBundlePatchTargetCodeTable = this.Output.EnsureTable(this.TableDefinitions["WixBundlePatchTargetCode"]);
                command.Execute();
            }

            // If catalog files exist, non-embedded payloads should validate with the catalogs.
            IEnumerable <WixBundleCatalogRow> catalogs = this.Output.Tables["WixBundleCatalog"].RowsAs <WixBundleCatalogRow>();

            if (catalogs.Any())
            {
                VerifyPayloadsWithCatalogCommand command = new VerifyPayloadsWithCatalogCommand();
                command.Catalogs = catalogs;
                command.Payloads = payloads.Values;
                command.Execute();
            }

            if (Messaging.Instance.EncounteredError)
            {
                return;
            }

            IEnumerable <PackageFacade> orderedFacades;
            IEnumerable <WixBundleRollbackBoundaryRow> boundaries;
            {
                OrderPackagesAndRollbackBoundariesCommand command = new OrderPackagesAndRollbackBoundariesCommand();
                command.Boundaries     = new RowDictionary <WixBundleRollbackBoundaryRow>(this.Output.Tables["WixBundleRollbackBoundary"]);
                command.PackageFacades = facades;
                command.WixGroupTable  = wixGroupTable;
                command.Execute();

                orderedFacades = command.OrderedPackageFacades;
                boundaries     = command.UsedRollbackBoundaries;
            }

            // Resolve any delayed fields before generating the manifest.
            if (this.DelayedFields.Any())
            {
                var resolveDelayedFieldsCommand = new ResolveDelayedFieldsCommand();
                resolveDelayedFieldsCommand.OutputType         = this.Output.Type;
                resolveDelayedFieldsCommand.DelayedFields      = this.DelayedFields;
                resolveDelayedFieldsCommand.ModularizationGuid = null;
                resolveDelayedFieldsCommand.VariableCache      = variableCache;
                resolveDelayedFieldsCommand.Execute();
            }

            // Set the overridable bundle provider key.
            this.SetBundleProviderKey(this.Output, bundleRow);

            // Import or generate dependency providers for packages in the manifest.
            this.ProcessDependencyProviders(this.Output, facades);

            // Update the bundle per-machine/per-user scope based on the chained packages.
            this.ResolveBundleInstallScope(bundleRow, orderedFacades);

            // Generate the core-defined BA manifest tables...
            {
                CreateBootstrapperApplicationManifestCommand command = new CreateBootstrapperApplicationManifestCommand();
                command.BundleRow          = bundleRow;
                command.ChainPackages      = orderedFacades;
                command.LastUXPayloadIndex = uxPayloadIndex;
                command.MsiFeatures        = this.Output.Tables["WixBundleMsiFeature"].RowsAs <WixBundleMsiFeatureRow>();
                command.Output             = this.Output;
                command.Payloads           = payloads;
                command.TableDefinitions   = this.TableDefinitions;
                command.TempFilesLocation  = this.IntermediateFolder;
                command.Execute();

                WixBundlePayloadRow baManifestPayload = command.BootstrapperApplicationManifestPayloadRow;
                payloads.Add(baManifestPayload);
            }

            //foreach (BinderExtension extension in this.Extensions)
            //{
            //    extension.PostBind(this.Context);
            //}

            // Create all the containers except the UX container first so the manifest (that goes in the UX container)
            // can contain all size and hash information about the non-UX containers.
            RowDictionary <WixBundleContainerRow> containers = new RowDictionary <WixBundleContainerRow>(this.Output.Tables["WixBundleContainer"]);

            ILookup <string, WixBundlePayloadRow> payloadsByContainer = payloads.Values.ToLookup(p => p.Container);

            int attachedContainerIndex = 1; // count starts at one because UX container is "0".

            IEnumerable <WixBundlePayloadRow> uxContainerPayloads = Enumerable.Empty <WixBundlePayloadRow>();

            foreach (WixBundleContainerRow container in containers.Values)
            {
                IEnumerable <WixBundlePayloadRow> containerPayloads = payloadsByContainer[container.Id];

                if (!containerPayloads.Any())
                {
                    if (container.Id != Compiler.BurnDefaultAttachedContainerId)
                    {
                        // TODO: display warning that we're ignoring container that ended up with no paylods in it.
                    }
                }
                else if (Compiler.BurnUXContainerId == container.Id)
                {
                    container.WorkingPath            = Path.Combine(this.IntermediateFolder, container.Name);
                    container.AttachedContainerIndex = 0;

                    // Gather the list of UX payloads but ensure the BootstrapperApplication Payload is the first
                    // in the list since that is the Payload that Burn attempts to load.
                    List <WixBundlePayloadRow> uxPayloads = new List <WixBundlePayloadRow>();

                    string baPayloadId = baRow.FieldAsString(0);

                    foreach (WixBundlePayloadRow uxPayload in containerPayloads)
                    {
                        if (uxPayload.Id == baPayloadId)
                        {
                            uxPayloads.Insert(0, uxPayload);
                        }
                        else
                        {
                            uxPayloads.Add(uxPayload);
                        }
                    }

                    uxContainerPayloads = uxPayloads;
                }
                else
                {
                    container.WorkingPath = Path.Combine(this.IntermediateFolder, container.Name);

                    // Add detached containers to the list of file transfers.
                    if (ContainerType.Detached == container.Type)
                    {
                        FileTransfer transfer;
                        if (FileTransfer.TryCreate(container.WorkingPath, Path.Combine(layoutDirectory, container.Name), true, "Container", container.SourceLineNumbers, out transfer))
                        {
                            transfer.Built = true;
                            fileTransfers.Add(transfer);
                        }
                    }
                    else // update the attached container index.
                    {
                        Debug.Assert(ContainerType.Attached == container.Type);

                        container.AttachedContainerIndex = attachedContainerIndex;
                        ++attachedContainerIndex;
                    }

                    this.CreateContainer(container, containerPayloads, null);
                }
            }

            // Create the bundle manifest then UX container.
            string manifestPath = Path.Combine(this.IntermediateFolder, "bundle-manifest.xml");
            {
                var command = new CreateBurnManifestCommand();
                command.BackendExtensions = this.BackendExtensions;
                command.Output            = this.Output;

                command.BundleInfo          = bundleRow;
                command.Chain               = chainRow;
                command.Containers          = containers;
                command.Catalogs            = catalogs;
                command.ExecutableName      = Path.GetFileName(this.OutputPath);
                command.OrderedPackages     = orderedFacades;
                command.OutputPath          = manifestPath;
                command.RollbackBoundaries  = boundaries;
                command.OrderedSearches     = orderedSearches;
                command.Payloads            = payloads;
                command.UXContainerPayloads = uxContainerPayloads;
                command.Execute();
            }

            WixBundleContainerRow uxContainer = containers[Compiler.BurnUXContainerId];
            this.CreateContainer(uxContainer, uxContainerPayloads, manifestPath);

            // Copy the burn.exe to a writable location then mark it to be moved to its final build location. Note
            // that today, the x64 Burn uses the x86 stub.
            string stubPlatform = (Platform.X64 == bundleRow.Platform) ? "x86" : bundleRow.Platform.ToString();

            string stubFile       = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), stubPlatform, "burn.exe");
            string bundleTempPath = Path.Combine(this.IntermediateFolder, Path.GetFileName(this.OutputPath));

            Messaging.Instance.OnMessage(WixVerboses.GeneratingBundle(bundleTempPath, stubFile));

            string bundleFilename = Path.GetFileName(this.OutputPath);
            if ("setup.exe".Equals(bundleFilename, StringComparison.OrdinalIgnoreCase))
            {
                Messaging.Instance.OnMessage(WixErrors.InsecureBundleFilename(bundleFilename));
            }

            FileTransfer bundleTransfer;
            if (FileTransfer.TryCreate(bundleTempPath, this.OutputPath, true, "Bundle", bundleRow.SourceLineNumbers, out bundleTransfer))
            {
                bundleTransfer.Built = true;
                fileTransfers.Add(bundleTransfer);
            }

            File.Copy(stubFile, bundleTempPath, true);
            File.SetAttributes(bundleTempPath, FileAttributes.Normal);

            this.UpdateBurnResources(bundleTempPath, this.OutputPath, bundleRow);

            // Update the .wixburn section to point to at the UX and attached container(s) then attach the containers
            // if they should be attached.
            using (BurnWriter writer = BurnWriter.Open(bundleTempPath))
            {
                FileInfo burnStubFile = new FileInfo(bundleTempPath);
                writer.InitializeBundleSectionData(burnStubFile.Length, bundleRow.BundleId);

                // Always attach the UX container first
                writer.AppendContainer(uxContainer.WorkingPath, BurnWriter.Container.UX);

                // Now append all other attached containers
                foreach (WixBundleContainerRow container in containers.Values)
                {
                    if (ContainerType.Attached == container.Type)
                    {
                        // The container was only created if it had payloads.
                        if (!String.IsNullOrEmpty(container.WorkingPath) && Compiler.BurnUXContainerId != container.Id)
                        {
                            writer.AppendContainer(container.WorkingPath, BurnWriter.Container.Attached);
                        }
                    }
                }
            }

            if (null != this.PdbFile)
            {
                Pdb pdb = new Pdb();
                pdb.Output = Output;
                pdb.Save(this.PdbFile);
            }

            this.FileTransfers    = fileTransfers;
            this.ContentFilePaths = payloads.Values.Where(p => p.ContentFile).Select(p => p.FullFileName).ToList();
        }