/// <summary>
        /// Compares the version of a Dynamics CRM solution in a target environment
        /// with a given version.
        /// </summary>
        /// <param name="version">The version which has to be checked.</param>
        /// <param name="solutionName">The unique name of the solution in the target environment.</param>
        /// <returns></returns>
        private bool CompareSolutionVersion(Version version, string solutionName)
        {
            var message = new RetrieveSolutionDataMessage(this.CrmOrganization)
            {
                UniqueName = solutionName,
            };

            var result = (RetrieveSolutionDataResult)this.CrmOrganization.Execute(message);

            if (result.Solution == null)
            {
                Logger.Log($"The solution {solutionName} was not found in the target system.", LogLevel.Info);
                return(true);
            }

            if (version == result.Solution.GetVersion())
            {
                if (this.OverwriteIfSameVersionExists)
                {
                    Logger.Log($"Found solution {result.Solution.UniqueName} with the same version {result.Solution.Version} in target system. Overwriting...", LogLevel.Info);
                    return(true);
                }

                Logger.Log($"Found solution {result.Solution.UniqueName} in target system - version {result.Solution.Version} is already loaded.", LogLevel.Info);
                return(false);
            }

            if (version < result.Solution.GetVersion())
            {
                Logger.Log($"Found solution {result.Solution.UniqueName} in target system - a higher version ({result.Solution.Version}) is already loaded.", LogLevel.Info);
                return(false);
            }
            else if (version > result.Solution.GetVersion())
            {
                Logger.Log($"Found solution {result.Solution.UniqueName} with lower version {result.Solution.Version} in target system - starting update.", LogLevel.Info);
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Deletes a solution from a Dynamics CRM organization.
        /// </summary>
        /// <returns>A result containing a Success boolean.</returns>
        public override Result Execute()
        {
            var message = new RetrieveSolutionDataMessage(this.CrmOrganization)
            {
                UniqueName = this.UniqueName,
            };
            var result = (RetrieveSolutionDataResult)this.CrmOrganization.Execute(message);

            if (result.Solution == null)
            {
                Logger.Log($"The solution {this.UniqueName} was not found in the target system", LogLevel.Warning);
            }

            Logger.Log($"Deleting solution {result.Solution.UniqueName} with version {result.Solution.Version} from target system.", LogLevel.Info);

            this.CrmOrganization.Delete("solution", result.Solution.SolutionId);

            var retrieveSolution = this.CrmOrganization.GetEntityByField("solution", "solutionid", result.Solution.SolutionId);

            if (retrieveSolution != null)
            {
                Logger.Log("The solution still exists.", LogLevel.Warning);

                return(new Result()
                {
                    Success = false,
                });
            }
            else
            {
                Logger.Log("The solution has been deleted.", LogLevel.Info);

                return(new Result()
                {
                    Success = true,
                });
            }
        }
        /// <summary>
        /// Exports a Dynamics CRM solution from a Dynamics CRM organization.
        /// </summary>
        /// <returns>A <seealso cref="Result"/> object</returns>
        public override Result Execute()
        {
            if (this.UniqueName == null || this.OutputFile == null)
            {
                Logger.Log(
                    $"Invalid input argument(s). UniqueName is {this.UniqueName}, OutputFile is {this.OutputFile}.",
                    LogLevel.Warning,
                    new InvalidOperationException("UniqueName and/or OutputFile is not in a correct format")
                    );
            }

            var message = new RetrieveSolutionDataMessage(this.CrmOrganization)
            {
                UniqueName = this.UniqueName,
            };

            var retrieveSolutionResult = (RetrieveSolutionDataResult)this.CrmOrganization.Execute(message);

            if (retrieveSolutionResult.Solution == null)
            {
                Logger.Log($"The solution {this.UniqueName} was not found in the target system.", LogLevel.Warning);
                return(new Result()
                {
                    Success = false
                });
            }

            if (retrieveSolutionResult.Solution.IsManaged == true)
            {
                Logger.Log($"The solution {this.UniqueName} is a managed solution and cannot be exported.", LogLevel.Warning);
                return(new Result()
                {
                    Success = false
                });
            }

            var result = this.CrmOrganization.Execute <ExportSolutionResponse>(new ExportSolutionRequest
            {
                SolutionName = this.UniqueName,
                Managed      = this.ExportAsManaged,
            });

            byte[] exportXml = result.ExportSolutionFile;

            // Overwrite the file if it already exists.
            if (File.Exists(this.OutputFile))
            {
                try
                {
                    File.Delete(this.OutputFile);
                }
                catch (IOException e)
                {
                    Logger.Log($"Exception thrown while deleting existing file: {e.Message}.", LogLevel.Warning, e);
                }
            }

            File.WriteAllBytes(this.OutputFile, exportXml);
            Logger.Log($"Solution {this.UniqueName} was exported successfully.", LogLevel.Info);

            return(new Result()
            {
                Success = true,
            });
        }