private void Initialize(RemoteSystemInfo remoteSystemInfo)
        {
            CheckConfig(Server, remoteSystemInfo);
            var userApphostConfig = Path.Combine(Environment.SystemDirectory,
                            @"inetsrv\config\applicationhost.config");
            var rootDefaultDocList = GetDefaultDocuments(userApphostConfig);
            CheckSessionState(userApphostConfig, Server);

            using (ServerManager manager = GetServerManager())
            {
                var config = manager.GetApplicationHostConfiguration();
                foreach (var appPool in manager.ApplicationPools)
                {
                    var isClassicMode = appPool.ManagedPipelineMode == ManagedPipelineMode.Classic ? true : false;
                    double netFxRuntimeVersion = 0;
                    if (!Double.TryParse(appPool.ManagedRuntimeVersion.TrimStart(new char[] { 'v', 'V' }),
                        out netFxRuntimeVersion))
                    {
                        netFxRuntimeVersion = 2.0;
                    }

                    Server.AppPools.Add(
                        new ApplicationPool(
                        isClassicMode,
                        netFxRuntimeVersion,
                        appPool.Enable32BitAppOnWin64,
                        appPool.Name));
                }

                foreach (var smSite in manager.Sites)
                {
                    string physicalPath = smSite.Applications["/"].VirtualDirectories["/"].PhysicalPath;
                    if (remoteSystemInfo != null)
                    {
                        physicalPath = remoteSystemInfo.GetRemotePath(physicalPath);
                    }
                    else
                    {
                        physicalPath = Environment.ExpandEnvironmentVariables(physicalPath);
                    }
                    var site = new Site(smSite.Name, smSite.Id);
                    site.PhysicalPath = physicalPath;
                    SetAuthPropertiesForSite(config, ref site);

                    if (Directory.Exists(physicalPath))
                    {
                        var webconfig = Path.Combine(physicalPath, "web.config");
                        if (File.Exists(webconfig))
                        {
                            CheckSessionState(webconfig, Server);
                            var localDefaultDocument = GetDefaultDocuments(webconfig);
                            if (localDefaultDocument.Count > 0)
                            {
                                site.DefaultDocuments = localDefaultDocument.Union(rootDefaultDocList,
                                    StringComparer.OrdinalIgnoreCase).ToList();
                            }
                            else
                            {
                                site.DefaultDocuments = rootDefaultDocList;
                            }
                        }
                    }

                    foreach (var application in smSite.Applications)
                    {
                        if (application.Path == "/")
                        {
                            site.AppPoolName = application.ApplicationPoolName;
                            var gacAssembly = new GacAssemblyDetector(physicalPath);
                            site.Add(gacAssembly.GetGacedAssemblies());

                            foreach (var vdir in smSite.Applications["/"].VirtualDirectories)
                            {
                                if (vdir.Path != "/")
                                {
                                    string vdirPhysicalPath = vdir.PhysicalPath;

                                    if (remoteSystemInfo != null)
                                    {
                                        vdirPhysicalPath = remoteSystemInfo.GetRemotePath(vdirPhysicalPath);
                                    }

                                    site.Add(new VirtualDirectory(vdir.Path, vdirPhysicalPath));
                                }
                            }

                            continue;
                        }

                        if (application.VirtualDirectories.Count > 0)
                        {
                            string appPhysicalPath = application.VirtualDirectories[0].PhysicalPath;
                            if (remoteSystemInfo != null && appPhysicalPath != "/")
                            {
                                appPhysicalPath = remoteSystemInfo.GetRemotePath(appPhysicalPath);
                            }

                            List<VirtualDirectory> listVdirs = new List<VirtualDirectory>();
                            foreach (var vdir in application.VirtualDirectories)
                            {
                                if (vdir.Path != "/")
                                {
                                    string vdirPhysicalPath = vdir.PhysicalPath;

                                    if (remoteSystemInfo != null)
                                    {
                                        vdirPhysicalPath = remoteSystemInfo.GetRemotePath(vdirPhysicalPath);
                                    }

                                    listVdirs.Add(new VirtualDirectory(vdir.Path, vdirPhysicalPath));
                                }
                            }

                            site.Add(new Application(application.Path, appPhysicalPath)
                            {
                                AppPoolName = application.ApplicationPoolName, VDirs = listVdirs
                            });

                            if (appPhysicalPath == "/")
                            {
                                continue;
                            }

                            var gacAssemblyForApp =
                                new GacAssemblyDetector(appPhysicalPath);
                            site.Add(gacAssemblyForApp.GetGacedAssemblies());
                        }
                    }

                    foreach (var binding in smSite.Bindings)
                    {
                        site.Add(new Binding(binding.BindingInformation, binding.Protocol));
                    }

                    site.IisVersion = this.Server.IISVersion;
                    site.OsVersion = this.Server.OSVersion;
                    GetDatabaseInfo(ref site, physicalPath, remoteSystemInfo != null ? remoteSystemInfo.ComputerName : string.Empty);
                    Server.Sites.Add(site);
                }
            }
        }
        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);
            }
        }