/// <summary>
        /// Decompile the UpgradedImages table.
        /// </summary>
        /// <param name="table">The table to decompile.</param>
        private void DecompileUpgradedImagesTable(Table table)
        {
            foreach (Row row in table.Rows)
            {
                Wix.UpgradeImage upgradeImage = new Wix.UpgradeImage();

                upgradeImage.Id = Convert.ToString(row[0]);

                upgradeImage.SourceFile = Convert.ToString(row[1]);

                if (null != row[2])
                {
                    upgradeImage.SourcePatch = Convert.ToString(row[2]);
                }

                if (null != row[3])
                {
                    string[] symbolPaths = (Convert.ToString(row[3])).Split(';');

                    foreach (string symbolPathString in symbolPaths)
                    {
                        Wix.SymbolPath symbolPath = new Wix.SymbolPath();

                        symbolPath.Path = symbolPathString;

                        upgradeImage.AddChild(symbolPath);
                    }
                }

                Wix.Family family = (Wix.Family)this.core.GetIndexedElement("ImageFamilies", Convert.ToString(row[4]));
                if (null != family)
                {
                    family.AddChild(upgradeImage);
                }
                else
                {
                    this.core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerCore.PrimaryKeyDelimiter), "Family", Convert.ToString(row[4]), "ImageFamilies"));
                }
                this.core.IndexElement(row, upgradeImage);
            }
        }
        /// <summary>
        /// Decompile the TargetImages table.
        /// </summary>
        /// <param name="table">The table to decompile.</param>
        private void DecompileTargetImagesTable(Table table)
        {
            foreach (Row row in table.Rows)
            {
                Wix.TargetImage targetImage = new Wix.TargetImage();

                targetImage.Id = Convert.ToString(row[0]);

                targetImage.SourceFile = Convert.ToString(row[1]);

                if (null != row[2])
                {
                    string[] symbolPaths = (Convert.ToString(row[3])).Split(';');

                    foreach (string symbolPathString in symbolPaths)
                    {
                        Wix.SymbolPath symbolPath = new Wix.SymbolPath();

                        symbolPath.Path = symbolPathString;

                        targetImage.AddChild(symbolPath);
                    }
                }

                targetImage.Order = Convert.ToInt32(row[4]);

                if (null != row[5])
                {
                    targetImage.Validation = Convert.ToString(row[5]);
                }

                if (0 != Convert.ToInt32(row[6]))
                {
                    targetImage.IgnoreMissingFiles = Wix.YesNoType.yes;
                }

                Wix.UpgradeImage upgradeImage = (Wix.UpgradeImage)this.core.GetIndexedElement("UpgradedImages", Convert.ToString(row[3]));
                if (null != upgradeImage)
                {
                    upgradeImage.AddChild(targetImage);
                }
                else
                {
                    this.core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerCore.PrimaryKeyDelimiter), "Upgraded", Convert.ToString(row[3]), "UpgradedImages"));
                }
                this.core.IndexElement(row, targetImage);
            }
        }
        /// <summary>
        /// Decompile the UpgradedFiles_OptionalData table.
        /// </summary>
        /// <param name="table">The table to decompile.</param>
        private void DecompileUpgradedFiles_OptionalDataTable(Table table)
        {
            foreach (Row row in table.Rows)
            {
                Wix.UpgradeFile upgradeFile = new Wix.UpgradeFile();

                upgradeFile.File = Convert.ToString(row[1]);

                if (null != row[2])
                {
                    string[] symbolPaths = (Convert.ToString(row[2])).Split(';');

                    foreach (string symbolPathString in symbolPaths)
                    {
                        Wix.SymbolPath symbolPath = new Wix.SymbolPath();

                        symbolPath.Path = symbolPathString;

                        upgradeFile.AddChild(symbolPath);
                    }
                }

                if (null != row[3] && 1 == Convert.ToInt32(row[3]))
                {
                    upgradeFile.AllowIgnoreOnError = Wix.YesNoType.yes;
                }

                if (null != row[4] && 0 != Convert.ToInt32(row[4]))
                {
                    upgradeFile.WholeFile = Wix.YesNoType.yes;
                }

                upgradeFile.Ignore = Wix.YesNoType.no;

                Wix.UpgradeImage upgradeImage = (Wix.UpgradeImage)this.core.GetIndexedElement("UpgradedImages", Convert.ToString(row[0]));
                if (null != upgradeImage)
                {
                    upgradeImage.AddChild(upgradeFile);
                }
                else
                {
                    this.core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerCore.PrimaryKeyDelimiter), "Upgraded", Convert.ToString(row[0]), "UpgradedImages"));
                }
            }
        }
        /// <summary>
        /// Decompile the TargetFiles_OptionalData table.
        /// </summary>
        /// <param name="table">The table to decompile.</param>
        private void DecompileTargetFiles_OptionalDataTable(Table table)
        {
            foreach (Row row in table.Rows)
            {
                Wix.TargetFile targetFile = (Wix.TargetFile)this.patchTargetFiles[row[0]];
                if (null == targetFile)
                {
                    targetFile = new Wix.TargetFile();

                    targetFile.Id = Convert.ToString(row[1]);

                    Wix.TargetImage targetImage = (Wix.TargetImage)this.core.GetIndexedElement("TargetImages", Convert.ToString(row[0]));
                    if (null != targetImage)
                    {
                        targetImage.AddChild(targetFile);
                    }
                    else
                    {
                        this.core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerCore.PrimaryKeyDelimiter), "Target", Convert.ToString(row[0]), "TargetImages"));
                    }
                    this.patchTargetFiles.Add(row.GetPrimaryKey(DecompilerCore.PrimaryKeyDelimiter), targetFile);
                }

                if (null != row[2])
                {
                    string[] symbolPaths = (Convert.ToString(row[2])).Split(';');

                    foreach (string symbolPathString in symbolPaths)
                    {
                        Wix.SymbolPath symbolPath = new Wix.SymbolPath();

                        symbolPath.Path = symbolPathString;

                        targetFile.AddChild(symbolPath);
                    }
                }

                if (null != row[3] && null != row[4])
                {
                    string[] ignoreOffsets = (Convert.ToString(row[3])).Split(',');
                    string[] ignoreLengths = (Convert.ToString(row[4])).Split(',');

                    if (ignoreOffsets.Length == ignoreLengths.Length)
                    {
                        for (int i = 0; i < ignoreOffsets.Length; i++)
                        {
                            Wix.IgnoreRange ignoreRange = new Wix.IgnoreRange();

                            if (ignoreOffsets[i].StartsWith("0x", StringComparison.Ordinal))
                            {
                                ignoreRange.Offset = Convert.ToInt32(ignoreOffsets[i].Substring(2), 16);
                            }
                            else
                            {
                                ignoreRange.Offset = Convert.ToInt32(ignoreOffsets[i], CultureInfo.InvariantCulture);
                            }

                            if (ignoreLengths[i].StartsWith("0x", StringComparison.Ordinal))
                            {
                                ignoreRange.Length = Convert.ToInt32(ignoreLengths[i].Substring(2), 16);
                            }
                            else
                            {
                                ignoreRange.Length = Convert.ToInt32(ignoreLengths[i], CultureInfo.InvariantCulture);
                            }

                            targetFile.AddChild(ignoreRange);
                        }
                    }
                    else
                    {
                        // TODO: warn
                    }
                }
                else if (null != row[3] || null != row[4])
                {
                    // TODO: warn about mismatch between columns
                }

                // the RetainOffsets column is handled in FinalizeFamilyFileRangesTable
            }
        }