public MetabaseReader(string migrationId, double iisVersion, RemoteSystemInfo remoteSystemInfo)
            : base(migrationId, iisVersion, remoteSystemInfo != null ? remoteSystemInfo.OSVersion : Environment.OSVersion.Version.ToString(), remoteSystemInfo != null ? remoteSystemInfo.ComputerName : Environment.MachineName)
        {
            _isLocal = remoteSystemInfo == null;
            var document = new XmlDocument();
            //#if DEBUG
            //            document.Load(@"E:\vsprojects\metabase.xml");
            //#else
            string metabasePath = _isLocal
                ? Path.Combine(Environment.SystemDirectory, @"inetsrv\metabase.xml")
                : remoteSystemInfo.RemoteMetabasePath;
            document.Load(metabasePath);
            //#endif

            var enable32Biton64 = false;
            var defaultAppPoolNode = document.SelectSingleNode(string.Format(NameSpaceAgnosticXPathFormat, "IIsApplicationPools"));
            var enable32bitAttribute = defaultAppPoolNode.Attributes["Enable32BitAppOnWin64"];
            if (enable32bitAttribute != null && !string.IsNullOrEmpty(enable32bitAttribute.Value))
            {
                enable32Biton64 = Convert.ToBoolean(enable32bitAttribute.Value);
            }

            XmlNode defaultServiceNode =
                document.SelectSingleNode(string.Format(NameSpaceAgnosticXPathFormat, "IIsWebService"));
            var netFxVersion =
                GetNetFxVersion(defaultServiceNode, null);
            var defaultAuthenticationType =
                GetAuthenticationType(
                    defaultServiceNode, EnabledAuthenticationType.Anonymous);
            var defaultDocList = GetDefaultDocList(defaultServiceNode, null);
            var iis5IsolationMode = false;
            var isolationModeAttribute = defaultServiceNode.Attributes["IIs5IsolationModeEnabled"];
            if (isolationModeAttribute != null && !string.IsNullOrEmpty(isolationModeAttribute.Value))
            {
                iis5IsolationMode = Convert.ToBoolean(isolationModeAttribute.Value);
            }

            var appPoolMap = new Dictionary<string, ApplicationPool>(StringComparer.OrdinalIgnoreCase);
            var appPoolNodes = document.SelectNodes(string.Format(NameSpaceAgnosticXPathFormat, "IIsApplicationPool"));
            foreach (XmlNode appPoolNode in appPoolNodes)
            {
                string name = string.Empty;
                var attribute = appPoolNode.Attributes["Location"];
                if (attribute != null && !string.IsNullOrEmpty(attribute.Value))
                {
                    name = attribute.Value.Replace("/LM/W3SVC/AppPools/", string.Empty);
                    appPoolMap[name] = new ApplicationPool(true, netFxVersion, enable32Biton64, name);
                }
            }

            var siteNodes = document.SelectNodes(string.Format(NameSpaceAgnosticXPathFormat, "IIsWebServer"));
            foreach (XmlNode siteNode in siteNodes)
            {
                var attribute = siteNode.Attributes["Location"];
                if (attribute != null)
                {
                    var m = SiteLocationRegex.Match(attribute.Value);
                    if (m.Success)
                    {
                        long siteId = Convert.ToInt64(m.Groups[1].Value);
                        string siteName = siteNode.Attributes["ServerComment"].Value;
                        var site = new Site(siteName, siteId);
                        string siteRootPath = attribute.Value + "/ROOT";
                        string lowerCaseSiteRootPath = attribute.Value + "/root";
                        var localAttribute = siteNode.Attributes["ServerBindings"];
                        if (localAttribute != null && !string.IsNullOrEmpty(localAttribute.Value))
                        {
                            AddBinding(localAttribute.Value, "http", ref site);
                        }

                        localAttribute = siteNode.Attributes["SecureBindings"];
                        if (localAttribute != null && !string.IsNullOrEmpty(localAttribute.Value))
                        {
                            AddBinding(localAttribute.Value, "https", ref site);
                        }

                        XmlNode currentSiteNode =
                            document.SelectSingleNode(string.Format(ExactAttributeXPath, "Location",
                                siteRootPath));
                        if (currentSiteNode == null)
                        {
                            currentSiteNode =
                            document.SelectSingleNode(string.Format(ExactAttributeXPath, "Location",
                                lowerCaseSiteRootPath));
                        }

                        if (currentSiteNode != null)
                        {
                            string physicalPath = currentSiteNode.Attributes["Path"].Value;
                            if (!_isLocal)
                            {
                                physicalPath = remoteSystemInfo.GetRemotePath(physicalPath);
                            }
                            var d = new GacAssemblyDetector(physicalPath);
                            site.Add(d.GetGacedAssemblies());
                            var tempAttribute = currentSiteNode.Attributes["AppPoolId"];
                            site.PhysicalPath = physicalPath;
                            if(tempAttribute == null || string.IsNullOrEmpty(tempAttribute.Value))
                            {
                                site.AppPoolName = "DefaultAppPool";
                            }
                            else
                            {
                                site.AppPoolName = tempAttribute.Value;
                            }

                            site.DefaultDocuments = GetDefaultDocList(currentSiteNode, defaultDocList);

                            site.EnabledAuthType = GetAuthenticationType(currentSiteNode, defaultAuthenticationType);
                            ApplicationPool appPool;
                            if (appPoolMap.TryGetValue(site.AppPoolName, out appPool))
                            {
                                appPool.NetFxVersion = GetNetFxVersion(currentSiteNode, netFxVersion);
                            }

                            GetDatabaseInfo(ref site, physicalPath, remoteSystemInfo != null ? remoteSystemInfo.ComputerName : string.Empty);
                        }

                        var appNodes = document.SelectNodes(string.Format(ContainsAttributeXPath, "Location", siteRootPath));
                        foreach (XmlNode appNode in appNodes)
                        {
                            var tempAttribute = appNode.Attributes["Path"];
                            if (tempAttribute == null)
                            {
                                // its just a directory
                                continue;
                            }

                            var physicalPath = tempAttribute.Value;
                            tempAttribute = appNode.Attributes["AppFriendlyName"];
                            if (tempAttribute == null)
                            {
                                // its just a vdir and not an app. No AppPool Settings
                                continue;
                            }

                            if (!_isLocal)
                            {
                                physicalPath = remoteSystemInfo.GetRemotePath(physicalPath);
                            }
                            var g = new GacAssemblyDetector(physicalPath);
                            site.Add(g.GetGacedAssemblies());
                            GetDatabaseInfo(ref site, physicalPath, remoteSystemInfo != null ? remoteSystemInfo.ComputerName : string.Empty);

                            string appName = tempAttribute.Value;
                            string appAppPoolName = string.Empty;
                            if (string.IsNullOrEmpty(appName))
                            {
                                appName = Path.GetFileName(physicalPath);
                            }

                            tempAttribute = appNode.Attributes["AppPoolId"];
                            if (tempAttribute != null)
                            {
                                appAppPoolName = tempAttribute.Value;
                            }

                            if (string.IsNullOrEmpty(appAppPoolName))
                            {
                                appAppPoolName = "DefaultAppPool";
                            }

                            ApplicationPool appPool;
                            if (appPoolMap.TryGetValue(appAppPoolName, out appPool))
                            {
                                appPool.NetFxVersion = GetNetFxVersion(appNode, netFxVersion);
                            }

                            var app = new Application(appName, physicalPath)
                            {
                                AppPoolName = appAppPoolName,
                            };

                            site.Add(app);
                        }

                        site.IIS5CompatMode = iis5IsolationMode;
                        Server.Sites.Add(site);
                    }
                }
            }

            foreach (var keyValue in appPoolMap)
            {
                Server.AppPools.Add(keyValue.Value);
            }
        }
 public void Add(Application app)
 {
     _applications.Add(app);
 }