private bool UpdateCrmAssembly(AssemblyItem assemblyItem, CrmConnection connection)
        {
            _dte.StatusBar.Animate(true, vsStatusAnimation.vsStatusAnimationDeploy);

            try
            {
                string outputFileName = _selectedProject.Properties.Item("OutputFileName").Value.ToString();
                string path = GetOutputPath() + outputFileName;

                //Build the project
                SolutionBuild solutionBuild = _dte.Solution.SolutionBuild;
                solutionBuild.BuildProject(_dte.Solution.SolutionBuild.ActiveConfiguration.Name, _selectedProject.UniqueName, true);

                if (solutionBuild.LastBuildInfo > 0)
                    return false;

                //Make sure Major and Minor versions match
                Version assemblyVersion = Version.Parse(_selectedProject.Properties.Item("AssemblyVersion").Value.ToString());
                if (assemblyItem.Version.Major != assemblyVersion.Major ||
                    assemblyItem.Version.Minor != assemblyVersion.Minor)
                {
                    _logger.WriteToOutputWindow("Error Updating Assembly In CRM: Changes To Major & Minor Versions Require Redeployment", Logger.MessageType.Error);
                    return false;
                }

                //Make sure assembly names match
                string assemblyName = _selectedProject.Properties.Item("AssemblyName").Value.ToString();
                if (assemblyName.ToUpper() != assemblyItem.Name.ToUpper())
                {
                    _logger.WriteToOutputWindow("Error Updating Assembly In CRM: Changes To Assembly Name Require Redeployment", Logger.MessageType.Error);
                    return false;
                }

                //Update CRM
                using (OrganizationService orgService = new OrganizationService(connection))
                {
                    Entity crmAssembly = new Entity("pluginassembly") { Id = assemblyItem.AssemblyId };
                    crmAssembly["content"] = Convert.ToBase64String(File.ReadAllBytes(path));

                    orgService.Update(crmAssembly);
                }

                //Update assembly name and version numbers
                assemblyItem.Version = assemblyVersion;
                assemblyItem.Name = _selectedProject.Properties.Item("AssemblyName").Value.ToString();
                assemblyItem.DisplayName = assemblyItem.Name + " (" + assemblyVersion + ")";
                assemblyItem.DisplayName += (assemblyItem.IsWorkflowActivity) ? " [Workflow]" : " [Plug-in]";

                return true;
            }
            catch (FaultException<OrganizationServiceFault> crmEx)
            {
                _logger.WriteToOutputWindow("Error Updating Assembly In CRM: " + crmEx.Message + Environment.NewLine + crmEx.StackTrace, Logger.MessageType.Error);
                return false;
            }
            catch (Exception ex)
            {
                _logger.WriteToOutputWindow("Error Updating Assembly In CRM: " + ex.Message + Environment.NewLine + ex.StackTrace, Logger.MessageType.Error);
                return false;
            }
            finally
            {
                _dte.StatusBar.Clear();
                _dte.StatusBar.Animate(false, vsStatusAnimation.vsStatusAnimationDeploy);
            }
        }
        private void AddOrUpdateMapping(AssemblyItem item)
        {
            try
            {
                var projectPath = Path.GetDirectoryName(_selectedProject.FullName);
                if (!ConfigFileExists(_selectedProject))
                {
                    _logger.WriteToOutputWindow("Error Updating Mappings In Config File: Missing CRMDeveloperExtensions.config File", Logger.MessageType.Error);
                    return;
                }

                XmlDocument doc = new XmlDocument();
                doc.Load(projectPath + "\\CRMDeveloperExtensions.config");

                //Update or delete existing mapping
                XmlNodeList assemblyNodes = doc.GetElementsByTagName("Assembly");
                if (assemblyNodes.Count > 0)
                {
                    foreach (XmlNode node in assemblyNodes)
                    {
                        XmlNode orgId = node["OrgId"];
                        if (orgId != null && orgId.InnerText.ToUpper() != _selectedConn.OrgId.ToUpper()) continue;

                        XmlNode projectNameNode = node["ProjectName"];
                        if (projectNameNode != null && projectNameNode.InnerText.ToUpper() != item.BoundProject.ToUpper())
                            continue;

                        if (string.IsNullOrEmpty(item.BoundProject) || item.AssemblyId == Guid.Empty)
                        {
                            //Delete
                            var parentNode = node.ParentNode;
                            if (parentNode != null)
                                parentNode.RemoveChild(node);
                        }
                        else
                        {
                            //Update
                            XmlNode assemblyIdNode = node["AssemblyId"];
                            if (assemblyIdNode != null)
                                assemblyIdNode.InnerText = item.AssemblyId.ToString();
                        }

                        doc.Save(projectPath + "\\CRMDeveloperExtensions.config");
                        return;
                    }
                }

                //Create new mapping
                XmlNodeList projects = doc.GetElementsByTagName("Assemblies");
                if (projects.Count > 0)
                {
                    XmlNode assembly = doc.CreateElement("Assembly");
                    XmlNode org = doc.CreateElement("OrgId");
                    org.InnerText = _selectedConn.OrgId;
                    assembly.AppendChild(org);
                    XmlNode projectNameNode2 = doc.CreateElement("ProjectName");
                    projectNameNode2.InnerText = item.BoundProject;
                    assembly.AppendChild(projectNameNode2);
                    XmlNode assemblyId = doc.CreateElement("AssemblyId");
                    assemblyId.InnerText = item.AssemblyId.ToString();
                    assembly.AppendChild(assemblyId);
                    projects[0].AppendChild(assembly);

                    doc.Save(projectPath + "\\CRMDeveloperExtensions.config");
                }
            }
            catch (Exception ex)
            {
                _logger.WriteToOutputWindow("Error Updating Mappings In Config File: " + ex.Message + Environment.NewLine + ex.StackTrace, Logger.MessageType.Error);
            }
        }
        private async void GetPlugins(string connString)
        {
            CrmConnection connection = CrmConnection.Parse(connString);

            _dte.StatusBar.Text = "Connecting to CRM and getting assemblies...";
            _dte.StatusBar.Animate(true, vsStatusAnimation.vsStatusAnimationSync);
            LockMessage.Content = "Working...";
            LockOverlay.Visibility = Visibility.Visible;

            EntityCollection results = await System.Threading.Tasks.Task.Run(() => RetrieveAssembliesFromCrm(connection));
            if (results == null)
            {
                _dte.StatusBar.Clear();
                LockOverlay.Visibility = Visibility.Hidden;
                MessageBox.Show("Error Retrieving Assemblies. See the Output Window for additional details.");
                return;
            }

            _logger.WriteToOutputWindow("Retrieved Assemblies From CRM", Logger.MessageType.Info);

            ObservableCollection<AssemblyItem> assemblies = new ObservableCollection<AssemblyItem>();

            AssemblyItem emptyItem = new AssemblyItem
            {
                AssemblyId = Guid.Empty,
                Name = String.Empty
            };
            assemblies.Add(emptyItem);

            foreach (var entity in results.Entities)
            {
                AssemblyItem aItem = new AssemblyItem
                {
                    AssemblyId = entity.Id,
                    Name = entity.GetAttributeValue<string>("name"),
                    Version = Version.Parse(entity.GetAttributeValue<string>("version")),
                    DisplayName = entity.GetAttributeValue<string>("name") + " (" + entity.GetAttributeValue<string>("version") + ")",
                    IsWorkflowActivity = false
                };

                //Only need to process the 1st assembly/type combination returned 
                if (assemblies.Count(a => a.AssemblyId == aItem.AssemblyId) > 0)
                    continue;

                if (entity.Contains("plugintype.isworkflowactivity"))
                    aItem.IsWorkflowActivity = (bool)entity.GetAttributeValue<AliasedValue>("plugintype.isworkflowactivity").Value;

                aItem.DisplayName += (aItem.IsWorkflowActivity) ? " [Workflow]" : " [Plug-in]";

                assemblies.Add(aItem);
            }

            assemblies = HandleMappings(assemblies);
            Assemblies.ItemsSource = assemblies;
            if (assemblies.Count(a => !string.IsNullOrEmpty(a.BoundProject)) > 0)
                Assemblies.SelectedItem = assemblies.First(a => !string.IsNullOrEmpty(a.BoundProject));
            Assemblies.IsEnabled = true;

            _dte.StatusBar.Clear();
            _dte.StatusBar.Animate(false, vsStatusAnimation.vsStatusAnimationSync);
            LockOverlay.Visibility = Visibility.Hidden;
        }
        private async void UpdateAssembly(AssemblyItem assemblyItem)
        {
            string projectName = _selectedProject.Name;
            Project project = GetProjectByName(projectName);
            if (project == null) return;

            string connString = _selectedConn.ConnectionString;
            if (connString == null) return;
            CrmConnection connection = CrmConnection.Parse(connString);

            LockMessage.Content = "Updating...";
            LockOverlay.Visibility = Visibility.Visible;

            bool success = await System.Threading.Tasks.Task.Run(() => UpdateCrmAssembly(assemblyItem, connection));

            LockOverlay.Visibility = Visibility.Hidden;

            if (success) { return; }

            MessageBox.Show("Error Updating Assembly. See the Output Window for additional details.");
            _dte.StatusBar.Clear();
        }