/// <summary>
        /// Generates the Summary page. xslTransform allows the calling method to select the appropriate transform.
        /// This allows the same summary method to generate the website page and the app page.
        /// </summary>
        /// <param name="xslTransform">Filename to use for Xsl transform</param>
        /// <param name="HostInstances">Collection of folding instances</param>
        /// <returns>HTML page as string</returns>
        public static String SummaryXml(String xslTransform, FoldingInstanceCollection HostInstances)
        {
            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.Load(PreferenceSet.Instance.AppPath + "\\XML\\Summary.XML");
            XmlElement xmlRootData = xmlDoc.DocumentElement;

            foreach (KeyValuePair <String, Base> kvp in HostInstances)
            {
                Base        Instance = kvp.Value;
                XmlDocument xmlFrag  = new XmlDocument();
                xmlFrag.Load(PreferenceSet.Instance.AppPath + "\\XML\\SummaryFrag.XML");
                XmlElement xmlData = xmlFrag.DocumentElement;

                XMLOps.setXmlNode(xmlData, "Name", Instance.Name);
                XMLOps.setXmlNode(xmlData, "PercentComplete", Instance.UnitInfo.PercentComplete.ToString());
                XMLOps.setXmlNode(xmlData, "Credit", String.Format("{0:0}", kvp.Value.CurrentProtein.Credit));
                XMLOps.setXmlNode(xmlData, "PPD", String.Format("{0:0.00}", Instance.UnitInfo.PPD));
                XMLOps.setXmlNode(xmlData, "PPW", String.Format("{0:0.00}", 7 * Instance.UnitInfo.PPD));
                XMLOps.setXmlNode(xmlData, "UPD", String.Format("{0:0.00}", Instance.UnitInfo.UPD));
                XMLOps.setXmlNode(xmlData, "UPW", String.Format("{0:0.00}", 7 * Instance.UnitInfo.UPD));
                XMLOps.setXmlNode(xmlData, "LastUpdate", Instance.LastRetrievalTime.ToString("d-MMM hh:mm tt"));

                Int32    addSeconds   = Convert.ToInt32((Instance.CurrentProtein.Frames - Instance.UnitInfo.FramesComplete) * Instance.UnitInfo.TimePerFrame.TotalSeconds);
                DateTime completeTime = DateTime.Now + new TimeSpan(0, 0, addSeconds);
                XMLOps.setXmlNode(xmlData, "CompleteTime", completeTime.ToLocalTime().ToString("d-MMM h:mm tt"));

                XmlNode xImpNode = xmlDoc.ImportNode(xmlFrag.ChildNodes[0], true);
                xmlRootData.AppendChild(xImpNode);
            }

            //    <LastUpdatedDate>10 August 2006</LastUpdatedDate>
            //    <LastUpdatedTime>9:25:23 pm</LastUpdatedTime>

            XmlNode xLastUpdDate = xmlDoc.CreateNode(XmlNodeType.Element, "LastUpdatedDate", null);

            xLastUpdDate.InnerText = DateTime.Now.ToLongDateString();

            XmlNode xLastUpdTime = xmlDoc.CreateNode(XmlNodeType.Element, "LastUpdatedTime", null);

            xLastUpdTime.InnerText = DateTime.Now.ToLongTimeString();

            xmlRootData.AppendChild(xLastUpdDate);
            xmlRootData.AppendChild(xLastUpdTime);

            return(XMLOps.Transform(xmlDoc, xslTransform));
        }
        /// <summary>
        /// Generates the Overview page. xslTransform allows the calling method to select the appropriate transform.
        /// This allows the same overview method to generate the website page and the app page.
        /// </summary>
        /// <param name="xslTransform">Filename to use for Xsl transform</param>
        /// <param name="HostInstances">Collection of folding instances</param>
        /// <returns>HTML page as string</returns>
        public static String OverviewXml(String xslTransform, FoldingInstanceCollection HostInstances)
        {
            Int32  badHostCount = 0, goodHostCount = 0, totalCompleted = 0;
            Double TotalPPD = 0, TotalUPD = 0;

            foreach (KeyValuePair <String, Base> kvp in HostInstances)
            {
                if (kvp.Value.LastRetrievalTime + new TimeSpan(0, 2 * (PreferenceSet.Instance.SyncTimeMinutes), 0) < DateTime.Now)
                {
                    badHostCount++;
                }
                else
                {
                    goodHostCount++;
                    TotalPPD       += kvp.Value.UnitInfo.PPD;
                    TotalUPD       += kvp.Value.UnitInfo.UPD;
                    totalCompleted += kvp.Value.TotalUnits;
                }
            }

            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.Load(PreferenceSet.Instance.AppPath + "\\XML\\Overview.XML");
            XmlElement xmlData = xmlDoc.DocumentElement;

            //<Overview>
            //    <TotalHosts>0</TotalHosts>
            //    <GoodHosts>0</GoodHosts>
            //    <BadHosts>0</BadHosts>
            //</Overview>

            XMLOps.setXmlNode(xmlData, "TotalHosts", HostInstances.Count.ToString());
            XMLOps.setXmlNode(xmlData, "GoodHosts", goodHostCount.ToString());
            XMLOps.setXmlNode(xmlData, "BadHosts", badHostCount.ToString());

            //    <EstPPD>0.00</EstPPD>
            //    <EstPPW>0.00</EstPPW>
            //    <EstUPD>0.00</EstUPD>
            //    <EstUPW>0.00</EstUPW>

            XMLOps.setXmlNode(xmlData, "EstPPD", String.Format("{0:0.00}", TotalPPD));
            XMLOps.setXmlNode(xmlData, "EstPPW", String.Format("{0:0.00}", TotalPPD * 7));
            XMLOps.setXmlNode(xmlData, "EstUPD", String.Format("{0:0.00}", TotalUPD));
            XMLOps.setXmlNode(xmlData, "EstUPW", String.Format("{0:0.00}", TotalUPD * 7));

            //    <AvEstPPD>0.00</AvEstPPD>
            //    <AvEstPPW>0.00</AvEstPPW>
            //    <AvEstUPD>0.00</AvEstUPD>
            //    <AvEstUPW>0.00</AvEstUPW>

            if (goodHostCount > 0)
            {
                XMLOps.setXmlNode(xmlData, "AvEstPPD", String.Format("{0:0.00}", TotalPPD / goodHostCount));
                XMLOps.setXmlNode(xmlData, "AvEstPPW", String.Format("{0:0.00}", TotalPPD * 7 / goodHostCount));
                XMLOps.setXmlNode(xmlData, "AvEstUPD", String.Format("{0:0.00}", TotalUPD / goodHostCount));
                XMLOps.setXmlNode(xmlData, "AvEstUPW", String.Format("{0:0.00}", TotalUPD * 7 / goodHostCount));
            }
            else
            {
                XMLOps.setXmlNode(xmlData, "AvEstPPD", "N/A");
                XMLOps.setXmlNode(xmlData, "AvEstPPW", "N/A");
                XMLOps.setXmlNode(xmlData, "AvEstUPD", "N/A");
                XMLOps.setXmlNode(xmlData, "AvEstUPW", "N/A");
            }

            //    <TotalCompleted>0</TotalCompleted>
            //    <LastUpdatedDate>Now</LastUpdatedDate>
            //    <LastUpdatedTime>Now</LastUpdatedTime>

            XMLOps.setXmlNode(xmlData, "TotalCompleted", totalCompleted.ToString());
            XMLOps.setXmlNode(xmlData, "LastUpdatedDate", DateTime.Now.ToLongDateString());
            XMLOps.setXmlNode(xmlData, "LastUpdatedTime", DateTime.Now.ToLongTimeString());

            return(XMLOps.Transform(xmlDoc, xslTransform));
        }