private void Publish(Guid[] webresourceIds, string[] filePaths, List <SelectedFile> files)
        {
            try
            {
                publishing = true;
                ToggleControls(false);

                Status.Update($"Attempting to publish: {string.Join("; ", filePaths.Select(Path.GetFileName))}");
                Controller.Trace("Attempting to publish: {0}", string.Join("; ", filePaths.Select(Path.GetFileName)));

                var base64Content = new string[webresourceIds.Length];
                for (var i = 0; i < webresourceIds.Length; i++)
                {
                    base64Content[i] = Convert.ToBase64String(File.ReadAllBytes(filePaths[i]));
                }

                var resultUpdate  = UpdateContent(webresourceIds, base64Content);
                var resultPublish = BeginPublish(resultUpdate);

                PublishedFiles.AddRange(files);

                EndPublish(resultPublish);
            }
            catch (Exception ex)
            {
                Status.Update("");
                Status.Update($"ERROR: {ex.Message}");
                Controller.Trace("ERROR: {0}", ex.Message);
                ToggleControl(connect, true);                 // enable the connect button so the user can try connecting to a different org
            }
        }
        private void EndPublish(Guid[] webresourceIds)
        {
            try
            {
                var percentComplete = (PublishedFiles.Count / (decimal)SelectedFiles.Count) * 100m;
                var msg             = $"Published: {PublishedFiles.Count} of {SelectedFiles.Count} ({percentComplete:N0}%)";
                Status.Update(msg);

                Controller.Trace("Published: {0}", string.Join("; ", webresourceIds));
                UpdateStatus(msg);
                Controller.Trace(msg);

                publishing = false;
                ToggleControls(true);

                var fileListString =
                    PublishedFiles.Select(file => file.FriendlyFilePath).Aggregate((file1, file2) => file1 + "\n" + file2);
                var confirmationMessage = "Files:\n" + fileListString;

                if (UnMappedCount > 0)
                {
                    if (Visible)
                    {
                        Invoke(new MethodInvoker(Hide));
                    }
                    return;
                }

                // once all the selected files are published we can close the dialog & show success message
                if (SelectedFiles.Count == PublishedFiles.Count && webresourceIds.Any())
                {
                    if (InvokeRequired)
                    {
                        BeginInvoke(new MethodInvoker(delegate
                        {
                            Status.Update("Succeeded ... \n" + confirmationMessage);
                            MessageBox.Show(confirmationMessage, "Successfully published files.",
                                            MessageBoxButtons.OK, MessageBoxIcon.Information);

                            Close();
                        }));
                    }
                    else
                    {
                        Status.Update("Succeeded ... \n" + confirmationMessage);
                        MessageBox.Show(confirmationMessage, "Successfully published files.", MessageBoxButtons.OK,
                                        MessageBoxIcon.Information);

                        if (Visible)
                        {
                            Invoke(new MethodInvoker(Close));
                        }
                    }
                }
                else
                {
                    confirmationMessage = "Files:\n" + fileListString;

                    if (InvokeRequired)
                    {
                        BeginInvoke(new MethodInvoker(delegate
                        {
                            Status.Update("Failed ... \n" + confirmationMessage);
                            MessageBox.Show(confirmationMessage, "Failed to publish files!",
                                            MessageBoxButtons.OK, MessageBoxIcon.Error);

                            Close();
                        }));
                    }
                    else
                    {
                        Status.Update("Failed ... \n" + confirmationMessage);
                        MessageBox.Show(confirmationMessage, "Failed to publish files!", MessageBoxButtons.OK, MessageBoxIcon.Error);

                        if (Visible)
                        {
                            Invoke(new MethodInvoker(Close));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Status.Update("");
                Status.Update($"ERROR: {ex.Message}");
                Controller.Trace("ERROR: {0}", ex.Message);
                ToggleControl(connect, true);                 // enable the connect button so the user can try connecting to a different org
            }
        }
        public void TryPublishing()
        {
            try
            {
                ToggleControls(false);

                if (Sdk != null)
                {
                    var existing = LinkerData.Get(LinkerDataPath);

                    var isFoundUnmapped = false;

                    if (!Relink && UnmappedFile == null)
                    {
                        var alreadyMappednMatching = SelectedFiles.Where(selectedFile =>
                        {
                            // grab correctly mapped files and publish them
                            return(existing.Mappings
                                   .Any(
                                       a =>
                                       a.SourceFilePath.Equals(selectedFile.FriendlyFilePath,
                                                               StringComparison.InvariantCultureIgnoreCase))
                                   &&
                                   // make sure we don't attempt to publish already published items
                                   !PublishedFiles.Any(
                                       a =>
                                       a.FilePath.Equals(selectedFile.FilePath,
                                                         StringComparison.InvariantCultureIgnoreCase)));
                        }).ToList();

                        UnMappedCount = UnMappedCount ?? SelectedFiles
                                        .Count(selectedFile =>
                        {
                            return(existing.Mappings.Where(
                                       a =>
                                       a.SourceFilePath.Equals(selectedFile.FriendlyFilePath,
                                                               StringComparison.InvariantCultureIgnoreCase))
                                   .Take(1).SingleOrDefault() == null);
                        });

                        if (alreadyMappednMatching.Count > 0)
                        {
                            PublishMappedResources(existing, alreadyMappednMatching);
                        }

                        // now find the unmapped files and mark them as unmapped, when the 'publish/link' button is clicked this unmapped file will be picked up by the same method, see 'if this.unmappedfile != null' check above
                        foreach (var selectedFile in SelectedFiles)
                        {
                            if (isFormClosing)
                            {
                                break;
                            }

                            var matchingItem = existing.Mappings
                                               .Where(
                                a =>
                                a.SourceFilePath.Equals(selectedFile.FriendlyFilePath,
                                                        StringComparison.InvariantCultureIgnoreCase))
                                               .Take(1).SingleOrDefault();

                            if (matchingItem == null)
                            {
                                unmappedLock.WaitOne();

                                if (isFormClosing)
                                {
                                    break;
                                }

                                UnMappedCount--;
                                MarkAsUnmapped(selectedFile);
                                isFoundUnmapped = true;
                            }
                        }
                    }

                    if (UnmappedFile != null && Visible)
                    // this property gets set if relink is set to true, otherwise this gets set by the logic below if there is no mapping
                    {
                        var existing1 = existing;
                        BeginInvoke(new MethodInvoker(() =>
                        {
                            try
                            {
                                PublishUnmappedResource(existing1);
                                existing.Save(LinkerDataPath);
                            }
                            catch (Exception ex)
                            {
                                Status.Update("");
                                Status.Update($"ERROR: {ex.Message}");
                                Controller.Trace("ERROR: {0}", ex.Message);
                                ToggleControl(connect, true);
                                // enable the connect button so the user can try connecting to a different org
                            }
                        }));
                        return;
                    }

                    if (isFoundUnmapped)
                    {
                        existing = LinkerData.Get(LinkerDataPath);
                    }

                    existing.Save(LinkerDataPath);
                    // save the mappings file regardless of the state of the publish since content would've been updated already
                }
                else
                {
                    ToggleControl(connect, true);                     // enable the connect button so the user can try connecting to a different org
                }
            }
            catch (Exception ex)
            {
                Status.Update("");
                Status.Update($"ERROR: {ex.Message}");
                Controller.Trace("ERROR: {0}", ex.Message);
                ToggleControl(connect, true);                 // enable the connect button so the user can try connecting to a different org
            }
        }