internal override bool TryParse(IMessageDialog dialog, FilePack filePack, out AddinResolution resolution)
        {
            resolution = null;
            if (!IsManifest(dialog, filePack.ManifestFile))
            {
                return(false);
            }

            var manifest = new XmlManifest
            {
                AddinHeader             = ReadHeader(),
                ExtensionDeclaration    = ReadDeclaration(),
                ExtensionImplementation = ReadImplementation(),
            };

            var addinDir         = Path.Combine(filePack.AddinProbeDirectory, filePack.AddinDirectoryName);
            var manifestFilePath = IoHelper.GetRelativePath(filePack.ManifestFile, addinDir);

            manifest.ManifestFile = new ManifestFileXml
            {
                Directory     = addinDir,
                FilePath      = manifestFilePath,
                LastWriteTime = IoHelper.GetLastWriteTime(filePack.ManifestFile),
                FileHash      = IoHelper.GetFileHash(filePack.ManifestFile)
            };

            if (filePack.AssemblyFiles != null)
            {
                manifest.AssemblyFiles = new List <AssemblyFileXml>();
                foreach (var assemblyFile in filePack.AssemblyFiles)
                {
                    var asmFile = new AssemblyFileXml
                    {
                        FilePath      = IoHelper.GetRelativePath(assemblyFile, addinDir),
                        LastWriteTime = IoHelper.GetLastWriteTime(assemblyFile)
                    };
                    manifest.AssemblyFiles.Add(asmFile);
                }
            }

            if (filePack.DataFiles != null)
            {
                manifest.DataFiles = new List <DataFileXml>();
                foreach (var dataFile in filePack.DataFiles)
                {
                    var dtFile = new DataFileXml {
                        FilePath = IoHelper.GetRelativePath(dataFile, addinDir)
                    };
                    manifest.DataFiles.Add(dtFile);
                }
            }

            return(manifest.Introspect(dialog) && manifest.TryParse(dialog, out resolution));
        }
        internal override bool TryParse(/*ILogger logger, */ ScanFilePack scanFilePack, out AddinManifest addinManifest)
        {
            addinManifest = null;
            if (!ShouldParse(scanFilePack.ManifestFile))
            {
                return(false);
            }

            var header = ReadHeader();

            var extensionSchema = ReadExtensionSchema();
            var extensions      = ReadExtensions();

            //if (extensionSchema == null && extensions == null)
            //    return false;

            var manifest = new XmlAddinManifest
            {
                AddinHeader     = header,
                ExtensionSchema = extensionSchema,
                Extensions      = extensions,
                AddinActivator  = ReadAddinActivator(),
            };

            var addinDir         = Path.Combine(scanFilePack.AddinProbingDirectory, scanFilePack.AddinDirectory);
            var manifestFilePath = IoHelper.GetRelativePath(scanFilePack.ManifestFile, addinDir);
            var fi = IoHelper.GetFileInfo(scanFilePack.ManifestFile);

            manifest.ManifestFile = new ManifestFileXml
            {
                Directory     = addinDir,
                FilePath      = manifestFilePath,
                LastWriteTime = fi.LastWriteTime,
                FileLength    = fi.Length,
                FileHash      = IoHelper.GetFileHash(scanFilePack.ManifestFile),
            };

            // if the manifest file does not contains a Files node, then use the ScanFilePack
            List <AssemblyFileXml> assemblyFiles;
            List <DataFileXml>     dataFiles;

            if (!TryReadFiles(addinDir, out assemblyFiles, out dataFiles))
            {
                if (scanFilePack.AssemblyFiles != null)
                {
                    assemblyFiles = new List <AssemblyFileXml>();
                    foreach (var assemblyFile in scanFilePack.AssemblyFiles)
                    {
                        var asmFile = new AssemblyFileXml
                        {
                            FilePath      = IoHelper.GetRelativePath(assemblyFile, addinDir),
                            LastWriteTime = IoHelper.GetLastWriteTime(assemblyFile)
                        };
                        assemblyFiles.Add(asmFile);
                    }
                }

                if (scanFilePack.DataFiles != null)
                {
                    dataFiles = new List <DataFileXml>();
                    foreach (var dataFile in scanFilePack.DataFiles)
                    {
                        var dtFile = new DataFileXml {
                            FilePath = IoHelper.GetRelativePath(dataFile, addinDir)
                        };
                        dataFiles.Add(dtFile);
                    }
                }
            }

            manifest.AssemblyFiles = assemblyFiles;
            manifest.DataFiles     = dataFiles;

            addinManifest = manifest;
            return(true);
        }
        ExtensionXml DoReadExtension(XmlNode node, string extensionPointPath, string parentPath)
        {
            if (node.NodeType != XmlNodeType.Element)// || node.Attributes == null || node.Attributes.Count == 0)
            {
                return(null);
            }

            var head = new ExtensionHeadXml
            {
                // get the extension builder path. this must be as the same as the ExtensionBuilder.Path
                ExtensionBuilderPath = extensionPointPath + SysConstants.PathSeparator + XmlHelper.GetNodeName(node),
                ParentPath           = parentPath
            };

            if (node.Attributes == null || node.Attributes.Count == 0)
            {
                return new ExtensionXml {
                           Head = head
                }
            }
            ;

            var data = new ExtensionDataXml();

            for (int i = 0; i < node.Attributes.Count; i++)
            {
                // no repeated definition now (e.g, one xml node has 2 id attribute defined)
                var attrib = node.Attributes[i];
                if (head.Id == null && XmlHelper.AttribueNameEquals(attrib, AttributeId))
                {
                    head.Id = XmlHelper.GetAttribueValue(attrib) ?? i.ToString();
                }
                else if (head.SiblingId == null &&
                         (XmlHelper.AttribueNameEquals(attrib, AttributeInsertBefore) || XmlHelper.AttribueNameEquals(attrib, AttributeInsertAfter)))
                {
                    if (XmlHelper.AttribueNameEquals(attrib, AttributeInsertBefore))
                    {
                        head.SiblingId        = XmlHelper.GetAttribueValue(attrib);
                        head.RelativePosition = RelativePosition.Before;
                    }
                    else if (XmlHelper.AttribueNameEquals(attrib, AttributeInsertAfter))
                    {
                        head.SiblingId        = XmlHelper.GetAttribueValue(attrib);
                        head.RelativePosition = RelativePosition.After;
                    }
                }
                else
                {
                    data.Add(XmlHelper.GetAttribueName(attrib), XmlHelper.GetAttribueValue(attrib));
                }
            }

            return(new ExtensionXml {
                Head = head, Data = data
            });
        }

        void DoReadExtensionRecursively(XmlNode node, string extensionPointPath, ExtensionXml parent)
        {
            var extension = DoReadExtension(node, extensionPointPath, parent.Head.Path);

            if (extension == null)
            {
                return;
            }
            parent.AddChild(extension);

            if (node.HasChildNodes)
            {
                for (int i = 0; i < node.ChildNodes.Count; i++)
                {
                    DoReadExtensionRecursively(node.ChildNodes[i], extensionPointPath, extension);
                }
            }
        }

        bool TryReadFiles(string addinDir, out List <AssemblyFileXml> assemblyFiles, out List <DataFileXml> dataFiles)
        {
            assemblyFiles = null;
            dataFiles     = null;

            if (_filesNode == null || _filesNode.NodeType != XmlNodeType.Element || !_filesNode.HasChildNodes)
            {
                return(false);
            }

            for (int i = 0; i < _filesNode.ChildNodes.Count; i++)
            {
                var childNode = _filesNode.ChildNodes[i];
                var path      = XmlHelper.GetMatchingAttribueValue(childNode, AttributePath);

                string fullPath;
                if (Path.IsPathRooted(path))
                {
                    if (!File.Exists(path))
                    {
                        continue;
                    }
                    fullPath = path;
                    path     = IoHelper.GetRelativePath(path, addinDir);
                }
                else
                {
                    fullPath = Path.Combine(addinDir, path);
                    if (!File.Exists(fullPath))
                    {
                        continue;
                    }
                }

                if (XmlHelper.IsMatchingNode(childNode, NodeFile))
                {
                    var dtFile = new DataFileXml {
                        FilePath = path
                    };
                    dataFiles = dataFiles ?? new List <DataFileXml>();
                    dataFiles.Add(dtFile);
                }
                else if (XmlHelper.IsMatchingNode(childNode, NodeAssembly))
                {
                    var asmFile = new AssemblyFileXml
                    {
                        FilePath      = path,
                        LastWriteTime = IoHelper.GetLastWriteTime(fullPath)
                    };
                    assemblyFiles = assemblyFiles ?? new List <AssemblyFileXml>();
                    assemblyFiles.Add(asmFile);
                }
            }

            return(assemblyFiles != null || dataFiles != null);
        }