/// <summary>
        /// Retrieves the relative path of a file based on
        /// the component it belongs to and its entry in
        /// the MSI directory table.
        /// </summary>
        /// <param name="database">The MSI database.</param>
        /// <param name="Name">The Name of the Folder</param>
        /// <param name="Parent">The Parent of the Folder</param>
        /// <param name="Default">The Relative Filesystem Path of the Folder</param>
        /// <param name="Path">The Path to the Folder from previous calls.</param>
        /// <param name="directoryTable">The MSI database view.</param>
        private void GetRelativePath(
            InstallerDatabase database,
            string Name,
            string Parent,
            string Default,
            StringBuilder Path,
            InstallerTable directoryTable) {
            if (Name == "TARGETDIR") {
                return;
            }

            for (int i = 0; i < commonFolderNames.Length; i++) {
                if (Name == commonFolderNames[i]) {
                    return;
                }
            }

            if (msi.directories != null) {
                ArrayList directoryList = new ArrayList();
                foreach(MSIRootDirectory directory in msi.directories) {
                    directoryList.Add(directory);
                }

                if (msi.properties != null) {
                    foreach (property property in msi.properties) {
                        if (Name == property.name) {
                            MSIDirectory directory = FindDirectory(Name);
                            if (directory == null) {
                                MSIRootDirectory propDirectory = new MSIRootDirectory();
                                propDirectory.name = Name;
                                propDirectory.root = "TARGETDIR";
                                propDirectory.foldername = ".";

                                directoryList.Add(propDirectory);

                                MSIRootDirectory[] rootDirs = new MSIRootDirectory[directoryList.Count];
                                directoryList.CopyTo(rootDirs);

                                msi.directories = rootDirs;
                            }

                            return;
                        }
                    }
                }
                if (Path.Length > 0) {
                    Path.Insert(0, @"\");
                }

                Path.Insert(0, Default);
                if (Parent != null) {
                    MSIDirectory PathInfo = FindDirectory(Parent);

                    if (PathInfo == null && msi.properties != null) {
                        foreach (property property in msi.properties) {
                            if (Parent == property.name) {
                                MSIRootDirectory directory = new MSIRootDirectory();
                                directory.name = Parent;
                                directory.root = "TARGETDIR";
                                directory.foldername = ".";

                                directoryList.Add(directory);

                                MSIRootDirectory[] rootDirs = new MSIRootDirectory[directoryList.Count];
                                directoryList.CopyTo(rootDirs);

                                msi.directories = rootDirs;

                                // Insert the Directory that is a Property
                                directoryTable.InsertRecord(Parent, "TARGETDIR", ".");

                                PathInfo = directory;

                                break;
                            }
                        }
                    }

                    string newParent = null;
                    if (PathInfo is MSIRootDirectory) {
                        newParent = ((MSIRootDirectory)PathInfo).root;
                    }
                    else {
                        newParent = FindParent(Parent);
                    }

                    GetRelativePath(database,
                        Parent, newParent,
                        PathInfo.foldername, Path, directoryTable);
                }
            }

        }
 private void AddTargetDir(ArrayList directoryList) {
     MSIRootDirectory targetDir = new MSIRootDirectory();
     targetDir.name = "TARGETDIR";
     targetDir.root = string.Empty;
     targetDir.foldername = "SourceDir";
     directoryList.Add(targetDir);
 }
 private void AddCommonDirectories(ArrayList directoryList) {
     for (int i = 0; i < commonFolderNames.Length; i++) {
         MSIRootDirectory commonDir = new MSIRootDirectory();
         commonDir.name = commonFolderNames[i];
         commonDir.root = "TARGETDIR";
         commonDir.foldername = ".";
         directoryList.Add(commonDir);
     }
 }
        /// <summary>
        /// Loads records for the Directories table.
        /// </summary>
        /// <param name="database">The MSI database.</param>
        private void LoadDirectories(InstallerDatabase database) {
            if (msi.directories == null)
                return;

            using (InstallerTable directoryTable = database.OpenTable("Directory")) {
                ArrayList directoryList = new ArrayList(msi.directories);

                AddTargetDir(directoryList);
                AddCommonDirectories(directoryList);

                MSIRootDirectory[] directories = new MSIRootDirectory[directoryList.Count];
                directoryList.CopyTo(directories);
                msi.directories = directories;

                int depth = 1;

                Log(Level.Verbose, "Adding Directories:");

                // Add directories from Task definition
                foreach (MSIRootDirectory directory in msi.directories) {
                    AddDirectory(database,
                        directoryTable, null,
                        directory, depth);
                }
            }
        }