private async Task CheckingPluginSteps(ConnectionData connectionData, CommonConfiguration commonConfig)
        {
            var service = await ConnectAndWriteToOutputAsync(connectionData);

            if (service == null)
            {
                return;
            }

            using (service.Lock())
            {
                var content = new StringBuilder();

                content.AppendLine(Properties.OutputStrings.ConnectingToCRM);
                content.AppendLine(connectionData.GetConnectionDescription());
                content.AppendFormat(Properties.OutputStrings.CurrentServiceEndpointFormat1, service.CurrentServiceEndpoint).AppendLine();

                var repositoryStep      = new SdkMessageProcessingStepRepository(service);
                var repositoryStepImage = new SdkMessageProcessingStepImageRepository(service);

                var stepEnum = await repositoryStep.FindSdkMessageProcessingStepWithEntityNameAsync(null, null, null, null, null);

                var imagesList = await repositoryStepImage.GetAllSdkMessageProcessingStepImageAsync(null, ColumnSetInstances.AllColumns);

                var imagesDictionary = imagesList.GroupBy(e => e.SdkMessageProcessingStepId.Id).ToDictionary(g => g.Key, g => g.ToList());

                var querySteps = stepEnum
                                 .OrderBy(ent => ent.EventHandler?.Name ?? "Unknown")
                                 .ThenBy(ent => ent.PrimaryObjectTypeCodeName)
                                 .ThenBy(ent => ent.SdkMessageId?.Name ?? "Unknown", MessageComparer.Comparer)
                                 .ThenBy(ent => ent.Stage.Value)
                                 .ThenBy(ent => ent.Mode.Value)
                                 .ThenBy(ent => ent.Rank)
                                 .ThenBy(ent => ent.Name)
                ;

                var pluginTypesWithConflicts = querySteps.GroupBy(step => new
                {
                    EventHandlerId = step.EventHandler.Id,
                    Stage          = step.Stage.Value,

                    EntityName = step.PrimaryObjectTypeCodeName,
                    Message    = step.SdkMessageId?.Name ?? "Unknown",

                    EventHandlerName = step.EventHandler?.Name ?? "Unknown",
                    step.Configuration,
                }).Where(gr => gr.Count() > 1);

                int pluginTypeNumber = 1;

                bool hasInfo = false;

                foreach (var gr in pluginTypesWithConflicts)
                {
                    hasInfo = true;

                    if (content.Length > 0)
                    {
                        content.AppendLine().AppendLine();
                    }

                    content.AppendFormat("{0}. {1}", pluginTypeNumber, gr.Key.EventHandlerName).AppendLine();

                    content.AppendFormat("Entity '{0}',   Message '{1}',   Stage '{2}'"
                                         , gr.Key.EntityName
                                         , gr.Key.Message
                                         , SdkMessageProcessingStepRepository.GetStageName(gr.Key.Stage, null)
                                         ).AppendLine();

                    if (!string.IsNullOrEmpty(gr.Key.Configuration))
                    {
                        content.AppendFormat("Configuration: {0}", gr.Key.Configuration).AppendLine();
                    }

                    foreach (var step in gr)
                    {
                        content.AppendFormat("Stage '{0}',   Rank {1},   Statuscode {2}"
                                             , SdkMessageProcessingStepRepository.GetStageName(step.Stage.Value, step.Mode.Value)
                                             , step.Rank.ToString()
                                             , step.FormattedValues[SdkMessageProcessingStep.Schema.Attributes.statuscode]
                                             ).AppendLine();

                        var queryImage = Enumerable.Empty <SdkMessageProcessingStepImage>();

                        if (imagesDictionary.TryGetValue(step.Id, out var listImages))
                        {
                            queryImage = from image in listImages
                                         orderby image.ImageType.Value, image.CreatedOn, image.Name
                            select image;
                        }

                        int numberImage = 1;

                        foreach (var image in queryImage)
                        {
                            string imageDescription = GetImageDescription(numberImage.ToString(), image);

                            var coll = imageDescription.Split(new string[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);

                            foreach (var item in coll)
                            {
                                content.Append(_tabSpacer).Append(_tabSpacer).AppendLine(item);
                            }

                            numberImage++;
                        }
                    }

                    pluginTypeNumber++;
                }

                if (!hasInfo)
                {
                    content.AppendLine(this._iWriteToOutput.WriteToOutput(connectionData, "No duplicates were found."));
                }

                commonConfig.CheckFolderForExportExists(this._iWriteToOutput);

                string fileName = string.Format("{0}.Checking Plugin Steps Duplicates at {1}.txt", connectionData.Name, EntityFileNameFormatter.GetDateString());

                string filePath = Path.Combine(commonConfig.FolderForExport, FileOperations.RemoveWrongSymbols(fileName));

                File.WriteAllText(filePath, content.ToString(), new UTF8Encoding(false));

                this._iWriteToOutput.WriteToOutput(connectionData, "Created file with Checking Plugin Steps Duplicates: {0}", filePath);

                this._iWriteToOutput.PerformAction(service.ConnectionData, filePath);
            }
        }
        private async Task CheckingPluginStepsRequiredComponents(ConnectionData connectionData, CommonConfiguration commonConfig)
        {
            var service = await ConnectAndWriteToOutputAsync(connectionData);

            if (service == null)
            {
                return;
            }

            using (service.Lock())
            {
                var content = new StringBuilder();

                content.AppendLine(Properties.OutputStrings.ConnectingToCRM);
                content.AppendLine(connectionData.GetConnectionDescription());
                content.AppendFormat(Properties.OutputStrings.CurrentServiceEndpointFormat1, service.CurrentServiceEndpoint).AppendLine();

                var repositoryStep = new SdkMessageProcessingStepRepository(service);

                var stepEnum = await repositoryStep.FindSdkMessageProcessingStepWithEntityNameAsync(null, null, null, null, null);

                var querySteps = stepEnum
                                 .OrderBy(ent => ent.EventHandler.Name)
                                 .ThenBy(ent => ent.PrimaryObjectTypeCodeName)
                                 .ThenBy(ent => ent.SdkMessageId.Name, MessageComparer.Comparer)
                                 .ThenBy(ent => ent.Stage.Value)
                                 .ThenBy(ent => ent.Mode.Value)
                                 .ThenBy(ent => ent.Rank)
                                 .ThenBy(ent => ent.Name)
                ;

                var repositoryMetadata = new EntityMetadataRepository(service);

                var dependencyRepository = new DependencyRepository(service);

                var listMetaData = await repositoryMetadata.GetEntitiesWithAttributesAsync();

                var dictEntity    = new Dictionary <Guid, EntityMetadata>();
                var dictAttribute = new Dictionary <Guid, AttributeMetadata>();

                bool hasInfo = false;

                foreach (var metaEntity in listMetaData)
                {
                    dictEntity.Add(metaEntity.MetadataId.Value, metaEntity);

                    foreach (var metaAttribute in metaEntity.Attributes)
                    {
                        dictAttribute.Add(metaAttribute.MetadataId.Value, metaAttribute);
                    }
                }

                foreach (var step in querySteps)
                {
                    var listRequired = await dependencyRepository.GetRequiredComponentsAsync((int)ComponentType.SdkMessageProcessingStep, step.Id);

                    var stepEntities   = GetSetEntites(step);
                    var stepAttributes = GetSetStepAttributes(step);

                    var componentsEntities   = GetSetComponentsEntites(listRequired, dictEntity);
                    var componentsAttributes = GetSetComponentsAttributes(listRequired, dictAttribute);

                    bool entitiesIsSame   = stepEntities.SequenceEqual(componentsEntities);
                    bool attributesIsSame = stepAttributes.SequenceEqual(componentsAttributes);

                    if (!entitiesIsSame || !attributesIsSame)
                    {
                        if (content.Length > 0)
                        {
                            content.AppendLine().AppendLine().AppendLine();
                        }

                        content.AppendFormat("{0}   Primary {1}   Secondary {2}   Message {3}   Stage {4}   Rank {5}   Status {6}   FilteringAttributes {7}",
                                             step.EventHandler?.Name ?? "Unknown"
                                             , step.PrimaryObjectTypeCodeName
                                             , step.SecondaryObjectTypeCodeName
                                             , step.SdkMessageId?.Name ?? "Unknown"
                                             , SdkMessageProcessingStepRepository.GetStageName(step.Stage.Value, step.Mode.Value)
                                             , step.Rank.ToString()
                                             , step.FormattedValues[SdkMessageProcessingStep.Schema.Attributes.statuscode]
                                             , step.FilteringAttributesStringsSorted
                                             ).AppendLine();

                        if (!entitiesIsSame)
                        {
                            hasInfo = true;

                            content.AppendLine("Conflict in entites.");

                            content.Append("Entities in plugin step description");

                            if (stepEntities.Count > 0)
                            {
                                content.AppendLine(":");

                                foreach (var item in stepEntities)
                                {
                                    content.AppendFormat("    {0}", item).AppendLine();
                                }
                            }
                            else
                            {
                                content.AppendLine(" are empty.");
                            }


                            content.Append("Entities in required components");

                            if (componentsEntities.Count > 0)
                            {
                                content.AppendLine(":");

                                foreach (var item in componentsEntities)
                                {
                                    content.AppendFormat("    {0}", item).AppendLine();
                                }
                            }
                            else
                            {
                                content.AppendLine(" are empty.");
                            }
                        }

                        if (!attributesIsSame)
                        {
                            hasInfo = true;

                            content.AppendLine("Conflict in attributes.");

                            content.Append("Attributes in plugin step description");

                            if (componentsEntities.Count > 0)
                            {
                                content.AppendLine(":");

                                foreach (var item in stepAttributes)
                                {
                                    content.AppendFormat("    {0}", item).AppendLine();
                                }
                            }
                            else
                            {
                                content.AppendLine(" are empty.");
                            }

                            content.Append("Attributes in required components");

                            if (componentsAttributes.Count > 0)
                            {
                                content.AppendLine(":");

                                foreach (var item in componentsAttributes)
                                {
                                    content.AppendFormat("    {0}", item).AppendLine();
                                }
                            }
                            else
                            {
                                content.AppendLine(" are empty.");
                            }
                        }
                    }
                }

                if (!hasInfo)
                {
                    content.AppendLine(this._iWriteToOutput.WriteToOutput(connectionData, "No conflicts were found."));
                }

                commonConfig.CheckFolderForExportExists(this._iWriteToOutput);

                string fileName = string.Format("{0}.Checking Plugin Steps Required Components at {1}.txt", connectionData.Name, EntityFileNameFormatter.GetDateString());

                string filePath = Path.Combine(commonConfig.FolderForExport, FileOperations.RemoveWrongSymbols(fileName));

                File.WriteAllText(filePath, content.ToString(), new UTF8Encoding(false));

                this._iWriteToOutput.WriteToOutput(connectionData, "Created file with Checking Plugin Steps Required Components: {0}", filePath);

                this._iWriteToOutput.PerformAction(service.ConnectionData, filePath);
            }
        }
        private async Task CheckingPluginImages(ConnectionData connectionData, CommonConfiguration commonConfig)
        {
            var service = await ConnectAndWriteToOutputAsync(connectionData);

            if (service == null)
            {
                return;
            }

            using (service.Lock())
            {
                var content = new StringBuilder();

                content.AppendLine(Properties.OutputStrings.ConnectingToCRM);
                content.AppendLine(connectionData.GetConnectionDescription());
                content.AppendFormat(Properties.OutputStrings.CurrentServiceEndpointFormat1, service.CurrentServiceEndpoint).AppendLine();

                var repositoryStep      = new SdkMessageProcessingStepRepository(service);
                var repositoryStepImage = new SdkMessageProcessingStepImageRepository(service);

                var stepEnum = await repositoryStep.FindSdkMessageProcessingStepWithEntityNameAsync(null, null, null, null, null);

                var imagesList = await repositoryStepImage.GetAllSdkMessageProcessingStepImageAsync(null, ColumnSetInstances.AllColumns);

                var imagesDictionary = imagesList.GroupBy(e => e.SdkMessageProcessingStepId.Id).ToDictionary(g => g.Key, g => g.ToList());

                var querySteps = stepEnum
                                 .OrderBy(ent => ent.EventHandler?.Name ?? "Unknown")
                                 .ThenBy(ent => ent.PrimaryObjectTypeCodeName)
                                 .ThenBy(ent => ent.SdkMessageId?.Name ?? "Unknown", MessageComparer.Comparer)
                                 .ThenBy(ent => ent.Stage.Value)
                                 .ThenBy(ent => ent.Mode.Value)
                                 .ThenBy(ent => ent.Rank)
                                 .ThenBy(ent => ent.Name)
                ;

                int stepNumber = 1;

                bool hasInfo = false;

                foreach (var step in querySteps)
                {
                    var queryImage = Enumerable.Empty <SdkMessageProcessingStepImage>();

                    if (imagesDictionary.TryGetValue(step.Id, out var listImages))
                    {
                        queryImage = from image in listImages
                                     orderby image.ImageType.Value, image.CreatedOn, image.Name
                        select image;
                    }

                    var preImages  = queryImage.Where(im => im.ImageType.Value == 0 || im.ImageType.Value == 2);
                    var postImages = queryImage.Where(im => im.ImageType.Value == 1 || im.ImageType.Value == 2);

                    var preImagesByEntityAlias = preImages.GroupBy(im => im.EntityAlias).Where(gr => gr.Count() > 1);
                    var preImagesByName        = preImages.GroupBy(im => im.EntityAlias).Where(gr => gr.Count() > 1);

                    var postImagesByEntityAlias = postImages.GroupBy(im => im.EntityAlias).Where(gr => gr.Count() > 1);
                    var postImagesByName        = postImages.GroupBy(im => im.EntityAlias).Where(gr => gr.Count() > 1);

                    var hasDuplicatesPreImagesByEntityAlias = preImagesByEntityAlias.Count() > 0;
                    var hasDuplicatesPreImagesByName        = preImagesByName.Count() > 0;

                    var hasDuplicatesPostImagesByEntityAlias = postImagesByEntityAlias.Count() > 0;
                    var hasDuplicatesPostImagesByName        = postImagesByName.Count() > 0;

                    if (hasDuplicatesPreImagesByEntityAlias ||
                        hasDuplicatesPreImagesByName ||
                        hasDuplicatesPostImagesByEntityAlias ||
                        hasDuplicatesPostImagesByName
                        )
                    {
                        if (content.Length > 0)
                        {
                            content.AppendLine().AppendLine();
                        }

                        hasInfo = true;

                        content.AppendFormat("{0}. {1}", stepNumber, step.EventHandler?.Name ?? "Unknown").AppendLine();

                        content.AppendFormat("Entity '{0}',   Message '{1}',   Stage '{2}',   Rank {3},   Statuscode {4}"
                                             , step.PrimaryObjectTypeCodeName
                                             , step.SdkMessageId?.Name ?? "Unknown"
                                             , SdkMessageProcessingStepRepository.GetStageName(step.Stage.Value, step.Mode.Value)
                                             , step.Rank.ToString()
                                             , step.FormattedValues[SdkMessageProcessingStep.Schema.Attributes.statuscode]
                                             ).AppendLine();

                        DescribeImages(content, stepNumber, hasDuplicatesPreImagesByEntityAlias, preImagesByEntityAlias, "Pre images duplicates by EntityAlias:");

                        DescribeImages(content, stepNumber, hasDuplicatesPreImagesByName, preImagesByName, "Pre images duplicates by Name:");

                        DescribeImages(content, stepNumber, hasDuplicatesPostImagesByEntityAlias, postImagesByEntityAlias, "Post images duplicates by EntityAlias:");

                        DescribeImages(content, stepNumber, hasDuplicatesPostImagesByName, postImagesByName, "Post images duplicates by Name:");

                        stepNumber++;
                    }
                }

                if (!hasInfo)
                {
                    content.AppendLine(this._iWriteToOutput.WriteToOutput(connectionData, "No duplicates were found."));
                }

                commonConfig.CheckFolderForExportExists(this._iWriteToOutput);

                string fileName = string.Format("{0}.Checking Plugin Images Duplicates at {1}.txt", connectionData.Name, EntityFileNameFormatter.GetDateString());

                string filePath = Path.Combine(commonConfig.FolderForExport, FileOperations.RemoveWrongSymbols(fileName));

                File.WriteAllText(filePath, content.ToString(), new UTF8Encoding(false));

                this._iWriteToOutput.WriteToOutput(connectionData, "Created file with Checking Plugin Images Duplicates: {0}", filePath);

                this._iWriteToOutput.PerformAction(service.ConnectionData, filePath);
            }
        }