internal static void SetWebPart(string url, Type oldType, Type newType, string title, Hashtable properties, bool publish, bool test)
        {
            using (SPSite site = new SPSite(url))
            using (SPWeb web = site.OpenWeb()) // The url contains a filename so AllWebs[] will not work unless we want to try and parse which we don't
            {
                bool cleanupContext = false;
                try
                {
                    if (HttpContext.Current == null)
                    {
                        cleanupContext = true;
                        HttpRequest httpRequest = new HttpRequest("", web.Url, "");
                        HttpContext.Current = new HttpContext(httpRequest, new HttpResponse(new StringWriter()));
                        SPControl.SetContextWeb(HttpContext.Current, web);
                    }

                    SPFile file = web.GetFile(url);

                    // file.Item will throw "The object specified does not belong to a list." if the url passed
                    // does not correspond to a file in a list.

                    bool checkIn = false;
                    if (file.InDocumentLibrary && !test)
                    {
                        if (!Utilities.IsCheckedOut(file.Item) || !Utilities.IsCheckedOutByCurrentUser(file.Item))
                        {
                            file.CheckOut();
                            checkIn = true;
                            // If it's checked out by another user then this will throw an informative exception so let it do so.
                        }
                    }

                    SPLimitedWebPartManager manager = null;
                    try
                    {
                        List<WebPart> webParts = Utilities.GetWebPartsByType(web, url, oldType, out manager);
                        foreach (var oldWebPart in webParts)
                        {
                            if (oldWebPart.IsClosed) continue;

                            string wpTitle = oldWebPart.Title;
                            if (string.IsNullOrEmpty(wpTitle)) wpTitle = oldWebPart.DisplayTitle;

                            if (!string.IsNullOrEmpty(title) &&
                                (oldWebPart.DisplayTitle.ToLowerInvariant() != title.ToLowerInvariant() &&
                                oldWebPart.Title.ToLowerInvariant() != title.ToLowerInvariant()))
                            {
                                continue;
                            }
                            Logger.Write("Replacing web part \"{0}\"...", wpTitle);
                            string zone = manager.GetZoneID(oldWebPart);
                            WebPart newWebPart = (WebPart)Activator.CreateInstance(newType);
                            if (SetProperties(oldWebPart, newWebPart, properties))
                            {
                                Logger.WriteWarning("An error was encountered setting web part properties so try one more time in case the error is the result of a sequencing issue.");
                                if (SetProperties(oldWebPart, newWebPart, properties))
                                {
                                    Logger.WriteWarning("Unable to set all properties for web part.");
                                }
                            }
                            if (!test)
                                manager.DeleteWebPart(oldWebPart);

                            try
                            {
                                if (!test)
                                {
                                    manager.AddWebPart(newWebPart, zone, oldWebPart.ZoneIndex);
                                }
                            }
                            catch (Exception)
                            {
                                ServicePointManager.ServerCertificateValidationCallback += delegate { return true; };

                                // We've not already added the web part so use the web service to do this.
                                using (WebPartPagesWebService.WebPartPagesWebService svc = new WebPartPagesWebService.WebPartPagesWebService())
                                {
                                    // We failed adding via the OM so try the web service as a fall back.
                                    svc.Url = manager.Web.Url + "/_vti_bin/WebPartPages.asmx";
                                    svc.Credentials = CredentialCache.DefaultCredentials;

                                    try
                                    {
                                        // Add the web part to the web service.  We use a web service because many
                                        // web parts require the SPContext.Current variables to be set which are
                                        // not set when run from a command line.
                                        StringBuilder sb = new StringBuilder();
                                        XmlTextWriter xmlWriter = new XmlTextWriter(new StringWriter(sb));
                                        xmlWriter.Formatting = Formatting.Indented;
                                        manager.ExportWebPart(newWebPart, xmlWriter);
                                        xmlWriter.Flush();

                                        svc.AddWebPartToZone(url, sb.ToString(), Storage.Shared, zone, oldWebPart.ZoneIndex);

                                    }
                                    catch (SoapException ex)
                                    {
                                        throw new Exception(ex.Detail.OuterXml);
                                    }
                                }
                            }
                            finally
                            {
                                oldWebPart.Dispose();
                                newWebPart.Dispose();
                            }
                            if (zone == "wpz" && file.InDocumentLibrary)
                            {
                                foreach (SPField field in file.Item.Fields)
                                {
                                    if (!field.ReadOnlyField && field is SPFieldMultiLineText && ((SPFieldMultiLineText)field).WikiLinking && file.Item[field.Id] != null)
                                    {
                                        string content = file.Item[field.Id].ToString();
                                        if (content.Contains(oldWebPart.ID.Replace("_", "-").Substring(2)))
                                        {
                                            Logger.Write("Replacing web part identifier in text field \"{0}\"...", field.InternalName);
                                            if (!test)
                                            {
                                                file.Item[field.Id] = content.Replace(oldWebPart.ID.Replace("_", "-").Substring(2), newWebPart.ID.Replace("_", "-").Substring(2));
                                                file.Item.SystemUpdate();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    finally
                    {
                        if (manager != null)
                        {
                            manager.Web.Dispose();
                            manager.Dispose();
                        }

                        if (!test)
                        {
                            if (checkIn)
                                file.CheckIn("Checking in changes to page due to web part being replaced with a different type.");
                            if (publish && file.InDocumentLibrary)
                            {
                                PublishItems pi = new PublishItems();
                                pi.PublishListItem(file.Item, file.Item.ParentList, false, "Replace-SPWebPartType", "Checking in changes to page due to web part being replaced with a different type.", null);
                            }
                        }
                    }
                }
                finally
                {
                    if (HttpContext.Current != null && cleanupContext)
                    {
                        HttpContext.Current = null;
                    }
                }

            }
        }
        internal static void SetWebPart(WebPart sourceWebPart, string targetUrl, string zone, int? zoneIndex, bool publish, bool test)
        {
            if (sourceWebPart.IsClosed)
            {
                sourceWebPart.Dispose();
                throw new Exception("The source web part is closed and cannot be copied.");
            }

            int zoneIndex1 = sourceWebPart.ZoneIndex;
            if (zoneIndex.HasValue)
                zoneIndex1 = zoneIndex.Value;
            Guid storageKey = Guid.NewGuid();
            string id = StorageKeyToID(storageKey);

            using (SPSite site = new SPSite(targetUrl))
            using (SPWeb web = site.OpenWeb()) // The url contains a filename so AllWebs[] will not work unless we want to try and parse which we don't
            {
                bool cleanupContext = false;
                try
                {
                    if (HttpContext.Current == null)
                    {
                        cleanupContext = true;
                        HttpRequest httpRequest = new HttpRequest("", web.Url, "");
                        HttpContext.Current = new HttpContext(httpRequest, new HttpResponse(new StringWriter()));
                        SPControl.SetContextWeb(HttpContext.Current, web);
                    }

                    SPFile file = web.GetFile(targetUrl);

                    // file.Item will throw "The object specified does not belong to a list." if the url passed
                    // does not correspond to a file in a list.

                    bool checkIn = false;
                    if (file.InDocumentLibrary && !test)
                    {
                        if (!Utilities.IsCheckedOut(file.Item) || !Utilities.IsCheckedOutByCurrentUser(file.Item))
                        {
                            file.CheckOut();
                            checkIn = true;
                            // If it's checked out by another user then this will throw an informative exception so let it do so.
                        }
                    }

                    SPLimitedWebPartManager manager = file.GetLimitedWebPartManager(PersonalizationScope.Shared);
                    try
                    {
                        string wpTitle = sourceWebPart.Title;
                        if (string.IsNullOrEmpty(wpTitle)) wpTitle = sourceWebPart.DisplayTitle;

                        Logger.Write("Copying web part \"{0}\"...", wpTitle);
                        WebPart newWebPart = (WebPart)Activator.CreateInstance(sourceWebPart.GetType());
                        if (SPCmdletReplaceWebPartType.SetProperties(sourceWebPart, newWebPart, null))
                        {
                            Logger.WriteWarning("An error was encountered setting web part properties so try one more time in case the error is the result of a sequencing issue.");
                            if (SPCmdletReplaceWebPartType.SetProperties(sourceWebPart, newWebPart, null))
                            {
                                Logger.WriteWarning("Unable to set all properties for web part.");
                            }
                        }

                        try
                        {
                            if (!test)
                            {
                                newWebPart.ID = id;

                                manager.AddWebPart(newWebPart, zone, zoneIndex1);
                            }
                        }
                        catch (Exception)
                        {
                            ServicePointManager.ServerCertificateValidationCallback += delegate { return true; };

                            // We've not already added the web part so use the web service to do this.
                            using (WebPartPagesWebService.WebPartPagesWebService svc = new WebPartPagesWebService.WebPartPagesWebService())
                            {
                                // We failed adding via the OM so try the web service as a fall back.
                                svc.Url = manager.Web.Url + "/_vti_bin/WebPartPages.asmx";
                                svc.Credentials = CredentialCache.DefaultCredentials;

                                try
                                {
                                    // Add the web part to the web service.  We use a web service because many
                                    // web parts require the SPContext.Current variables to be set which are
                                    // not set when run from a command line.
                                    StringBuilder sb = new StringBuilder();
                                    XmlTextWriter xmlWriter = new XmlTextWriter(new StringWriter(sb));
                                    xmlWriter.Formatting = Formatting.Indented;
                                    manager.ExportWebPart(newWebPart, xmlWriter);
                                    xmlWriter.Flush();

                                    svc.AddWebPartToZone(targetUrl, sb.ToString(), Storage.Shared, zone, zoneIndex1);

                                }
                                catch (SoapException ex)
                                {
                                    throw new Exception(ex.Detail.OuterXml);
                                }
                            }
                        }
                        finally
                        {
                            sourceWebPart.Dispose();
                            newWebPart.Dispose();
                        }
                        if (zone == "wpz" && file.InDocumentLibrary)
                        {
                            foreach (SPField field in file.Item.Fields)
                            {
                                if (!field.ReadOnlyField && field is SPFieldMultiLineText && ((SPFieldMultiLineText)field).WikiLinking)
                                {
                                    string content = null;
                                    if (file.Item[field.Id] != null)
                                        content = file.Item[field.Id].ToString();

                                    string div = string.Format(CultureInfo.InvariantCulture, "<div class=\"ms-rtestate-read ms-rte-wpbox\" contentEditable=\"false\"><div class=\"ms-rtestate-read {0}\" id=\"div_{0}\"></div><div style='display:none' id=\"vid_{0}\"/></div>", new object[] { storageKey.ToString("D") });
                                    content += div;
                                    Logger.Write("Adding web part to text field \"{0}\"...", field.InternalName);
                                    if (!test)
                                    {
                                        file.Item[field.Id] = content;
                                        file.Item.SystemUpdate();
                                    }
                                }
                            }
                        }

                    }
                    finally
                    {
                        if (manager != null)
                        {
                            manager.Web.Dispose();
                            manager.Dispose();
                        }

                        if (!test)
                        {
                            if (checkIn)
                                file.CheckIn("Checking in changes to page due to web part being replaced with a different type.");
                            if (publish && file.InDocumentLibrary)
                            {
                                PublishItems pi = new PublishItems();
                                pi.PublishListItem(file.Item, file.Item.ParentList, false, "Copy-SPWebPart", "Checking in changes to page due to web part being copied from another page.", null);
                            }
                        }
                    }
                }
                finally
                {
                    if (HttpContext.Current != null && cleanupContext)
                    {
                        HttpContext.Current = null;
                    }
                }

            }
        }
        internal static void Move(string url, string webPartId, string webPartTitle, string webPartZone, string webPartZoneIndex, bool publish)
        {
            using (SPSite site = new SPSite(url))
            using (SPWeb web = site.OpenWeb()) // The url contains a filename so AllWebs[] will not work unless we want to try and parse which we don't
            {
                SPFile file = web.GetFile(url);
                bool checkIn = false;
                if (file.InDocumentLibrary)
                {
                    if (!Utilities.IsCheckedOut(file.Item) || !Utilities.IsCheckedOutByCurrentUser(file.Item))
                    {
                        file.CheckOut();
                        checkIn = true;
                        // If it's checked out by another user then this will throw an informative exception so let it do so.
                    }
                }

                string displayTitle = string.Empty;
                try
                {
                    WebPart wp;
                    SPLimitedWebPartManager manager;
                    if (!string.IsNullOrEmpty(webPartId))
                    {
                        wp = Utilities.GetWebPartById(web, url, webPartId, out manager);
                    }
                    else
                    {
                        wp = Utilities.GetWebPartByTitle(web, url, webPartTitle, out manager);
                        if (wp == null)
                        {
                            throw new SPException(
                                "Unable to find specified web part. Try specifying the -id parameter instead (use Get-SPWebPartList to get the ID)");
                        }
                    }

                    if (wp == null)
                    {
                        throw new SPException("Unable to find specified web part.");
                    }

                    string zoneID = manager.GetZoneID(wp);
                    int zoneIndex = wp.ZoneIndex;

                    if (!string.IsNullOrEmpty(webPartZone))
                        zoneID = webPartZone;
                    if (!string.IsNullOrEmpty(webPartZoneIndex))
                        zoneIndex = int.Parse(webPartZoneIndex);

                    // Set this so that we can add it to the check-in comment.
                    displayTitle = wp.DisplayTitle;

                    manager.MoveWebPart(wp, zoneID, zoneIndex);
                    manager.SaveChanges(wp);
                }
                finally
                {
                    if (checkIn)
                        file.CheckIn("Checking in changes to page due to moving of web part " + displayTitle);
                    if (publish && file.InDocumentLibrary)
                    {
                        PublishItems pi = new PublishItems();
                        pi.PublishListItem(file.Item, file.Item.ParentList, false, "Move-SPWebPart", "Checking in changes to page due to moving of web part " + displayTitle, null);
                    }
                }
            }
        }
        internal static void SetWebPart(string url, SetWebPartStateAction action, string webPartId, string webPartTitle, string webPartZone, string webPartZoneIndex, Hashtable props, bool publish)
        {
            using (SPSite site = new SPSite(url))
            using (SPWeb web = site.OpenWeb()) // The url contains a filename so AllWebs[] will not work unless we want to try and parse which we don't
            {
                bool cleanupContext = false;
                try
                {
                    if (HttpContext.Current == null)
                    {
                        cleanupContext = true;
                        HttpRequest httpRequest = new HttpRequest("", web.Url, "");
                        HttpContext.Current = new HttpContext(httpRequest, new HttpResponse(new StringWriter()));
                        SPControl.SetContextWeb(HttpContext.Current, web);
                    }

                    SPFile file = web.GetFile(url);

                    // file.Item will throw "The object specified does not belong to a list." if the url passed
                    // does not correspond to a file in a list.

                    bool checkIn = false;
                    if (file.InDocumentLibrary)
                    {
                        if (!Utilities.IsCheckedOut(file.Item) || !Utilities.IsCheckedOutByCurrentUser(file.Item))
                        {
                            file.CheckOut();
                            checkIn = true;
                            // If it's checked out by another user then this will throw an informative exception so let it do so.
                        }
                    }

                    string displayTitle = string.Empty;
                    WebPart wp = null;
                    SPLimitedWebPartManager manager = null;
                    try
                    {
                        if (!string.IsNullOrEmpty(webPartId))
                        {
                            wp = Utilities.GetWebPartById(web, url, webPartId, out manager);
                        }
                        else
                        {
                            wp = Utilities.GetWebPartByTitle(web, url, webPartTitle, out manager);
                            if (wp == null)
                            {
                                throw new SPException(
                                    "Unable to find specified web part using title \"" + webPartTitle + "\". Try specifying the -id parameter instead (use Get-SPWebPartList to get the ID)");
                            }
                        }

                        if (wp == null)
                        {
                            throw new SPException("Unable to find specified web part.");
                        }

                        // Set this so that we can add it to the check-in comment.
                        displayTitle = wp.DisplayTitle;

                        if (action == SetWebPartStateAction.Delete)
                            manager.DeleteWebPart(wp);
                        else if (action == SetWebPartStateAction.Close)
                            manager.CloseWebPart(wp);
                        else if (action == SetWebPartStateAction.Open)
                            manager.OpenWebPart(wp);

                        if (action != SetWebPartStateAction.Delete)
                        {
                            string zoneID = manager.GetZoneID(wp);
                            int zoneIndex = wp.ZoneIndex;

                            if (!string.IsNullOrEmpty(webPartZone))
                                zoneID = webPartZone;
                            if (!string.IsNullOrEmpty(webPartZoneIndex))
                                zoneIndex = int.Parse(webPartZoneIndex);

                            manager.MoveWebPart(wp, zoneID, zoneIndex);

                            if (props != null && props.Count > 0)
                            {
                                SetWebPartProperties(wp, props);
                            }
                            manager.SaveChanges(wp);
                        }

                    }
                    finally
                    {
                        if (manager != null)
                        {
                            manager.Web.Dispose();
                            manager.Dispose();
                        }
                        if (wp != null)
                            wp.Dispose();

                        if (checkIn)
                            file.CheckIn("Checking in changes to page due to state change of web part " + displayTitle);
                        if (publish && file.InDocumentLibrary)
                        {
                            PublishItems pi = new PublishItems();
                            pi.PublishListItem(file.Item, file.Item.ParentList, false, "Set-SPWebPart", "Checking in changes to page due to state change of web part " + displayTitle, null);
                        }

                    }
                }
                finally
                {
                    if (HttpContext.Current != null && cleanupContext)
                    {
                        HttpContext.Current = null;
                    }
                }

            }
        }